Skip to content

chore(desktop): bump version to 0.0.34#482

Closed
saddlepaddle wants to merge 7 commits intomainfrom
homely-quail-98f31a
Closed

chore(desktop): bump version to 0.0.34#482
saddlepaddle wants to merge 7 commits intomainfrom
homely-quail-98f31a

Conversation

@saddlepaddle
Copy link
Copy Markdown
Collaborator

@saddlepaddle saddlepaddle commented Dec 23, 2025

Bumps desktop app version to 0.0.34.

This PR was automatically created by the release script.

Summary by CodeRabbit

Release Notes

  • Chores
    • Updated database infrastructure for improved data persistence and reliability.
    • Added new database dependencies to support enhanced data storage capabilities.
    • Migrated application data to use a more robust persistence mechanism with automatic legacy data migration support.
    • Extended native module support for the desktop application build process.

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

saddlepaddle and others added 6 commits December 22, 2025 20:03
- Add @superset/local-db package with Drizzle ORM schema
- Migrate all database operations from lowdb (db.json) to SQLite
- Add better-sqlite3 native module support for Electron
- Update all routers to use Drizzle queries
- Remove lowdb dependency
- Add UUID defaults for all ID fields (prep for local-first)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove workspaces.test.ts that was testing mock behavior rather than
  real logic (tests were mocking Drizzle's complex query API)
- Fix formatting in local-db/index.ts
- The git parsing logic these tests covered should be tested via
  integration tests or by extracting pure functions

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add more electron exports to test mock (clipboard, screen, Notification,
Menu) to prevent intermittent test failures from unresolved imports.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add lowdb ^7.0.1 back to desktop dependencies (app-state still uses it)
- Add crypto import from node:crypto in local-db schema.ts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace crypto.randomUUID() with uuid v4 to avoid node:crypto module
resolution issues in CI environments.

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

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

coderabbitai Bot commented Dec 23, 2025

Warning

Rate limit exceeded

@saddlepaddle has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 6 minutes and 4 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 6c2ef2e and 25feb88.

📒 Files selected for processing (2)
  • apps/desktop/electron-builder.ts
  • apps/desktop/scripts/copy-native-modules.ts

Walkthrough

This PR migrates the desktop application's data persistence layer from lowdb (in-memory JSON) to SQLite with Drizzle ORM. It introduces a new @superset/local-db package containing the database schema and migrations, adds better-sqlite3 as a runtime dependency, updates all desktop routers to use the new localDb API with SQL queries, removes the legacy in-memory db module, and updates related imports throughout the codebase. The migration includes one-time legacy data import from the old JSON format to SQLite on app startup.

Changes

Cohort / File(s) Summary
New Local Database Package
packages/local-db/*
Introduces complete SQLite + Drizzle ORM schema package with four main tables (projects, worktrees, workspaces, settings), Zod validation schemas, table relations, drizzle-kit migrations, TypeScript configuration, and package exports for both root and schema subpaths.
Desktop Package & Version Bumps
apps/desktop/package.json, apps/admin/package.json
Adds dependencies: drizzle-orm, better-sqlite3 with types, and @superset/local-db workspace dependency to desktop; adds drizzle-orm to admin. Bumps desktop version from 0.0.33 to 0.0.34.
Build Configuration & Native Module Setup
apps/desktop/electron.vite.config.ts, apps/desktop/electron-builder.ts, apps/desktop/scripts/copy-native-modules.ts
Extends ASAR unpack list and build rules for better-sqlite3; adds conditional copying of database migrations to resources; adds better-sqlite3 to externalized native modules; includes better-sqlite3 in NATIVE\_MODULES list.
Database Infrastructure
apps/desktop/src/main/lib/local-db/index.ts
New module initializing SQLite with Drizzle ORM, resolving migrations directory, executing schema migrations, and handling one-time legacy lowdb→SQLite data migration with error handling and backup of old JSON file.
Old Database Module Removal
apps/desktop/src/main/lib/db/index.ts, apps/desktop/src/main/lib/db/schemas.ts, apps/desktop/src/main/index.ts
Removes lowdb-based db initialization (initDb, db proxy), removes all schema interfaces/types (Project, Workspace, Settings, etc.), and replaces initDb call with localDb import and console logging.
Desktop Router Migrations (Data Access)
apps/desktop/src/lib/trpc/routers/projects/projects.ts, apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts, apps/desktop/src/lib/trpc/routers/settings/index.ts, apps/desktop/src/lib/trpc/routers/terminal/terminal.ts, apps/desktop/src/lib/trpc/routers/changes/branches.ts, apps/desktop/src/lib/trpc/routers/config/config.ts, apps/desktop/src/lib/trpc/routers/external/index.ts
Systematically migrate from in-memory db access (db.data.*) to Drizzle ORM queries/mutations using localDb.select/insert/update/delete patterns. Includes cascading updates to related tables and self-healing logic for invalid settings.
Router Helpers & Utilities
apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts, apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts, apps/desktop/src/lib/trpc/routers/external/helpers.ts, apps/desktop/src/main/windows/main.ts, apps/desktop/src/main/lib/notification-sound.ts
Update to use localDb for workspace/worktree/settings lookups; import type updates from old db/schemas to @superset/local-db.
Import Path Updates (Renderer & Types)
apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx, apps/desktop/src/renderer/screens/main/components/.../* (6 files)
Change type imports for CheckItem, TerminalPreset, ExternalApp from main/lib/db/schemas to @superset/local-db. No runtime logic changes.
Test Infrastructure
apps/desktop/test-setup.ts, apps/desktop/src/lib/trpc/routers/workspaces/workspaces.test.ts
Extends Electron mocks with app/shell/clipboard/screen/Notification/Menu APIs; adds comprehensive localDb mock with chainable select/insert/update/delete methods. Removes entire canDelete endpoint test suite (200+ lines).
Package Exports
packages/db/src/index.ts
Removes re-exports of drizzle-orm operators (and, eq, gt, gte, inArray, lt, lte, ne, not, or).
Database Migrations
packages/local-db/drizzle/0000_initial_schema.sql, packages/local-db/drizzle/meta/*
SQL schema creating projects, worktrees, workspaces, settings tables with foreign keys and indices; Drizzle meta/journal files tracking migration state.

Sequence Diagram

sequenceDiagram
    actor App as Electron App
    participant Init as Startup (main/index.ts)
    participant LocalDB as LocalDb<br/>(Drizzle + SQLite)
    participant SQLite as SQLite<br/>Database
    participant LegacyDB as Legacy<br/>db.json
    
    App->>Init: Start application
    Init->>LocalDB: import localDb
    
    rect rgb(200, 220, 255)
    Note over LocalDB,SQLite: Database Initialization
    LocalDB->>LocalDB: Resolve migrations dir<br/>(prod/dev/test layouts)
    LocalDB->>SQLite: Execute schema migrations<br/>(0000_initial_schema.sql)
    LocalDB->>LocalDB: Check for legacy db.json
    end
    
    alt Legacy data exists AND SQLite empty
        rect rgb(255, 230, 200)
        Note over LocalDB,LegacyDB: One-time Data Migration
        LocalDB->>LegacyDB: Read legacy JSON<br/>(projects, workspaces, etc.)
        LocalDB->>SQLite: INSERT projects, worktrees,<br/>workspaces, settings
        LocalDB->>LocalDB: Deduplicate workspaces<br/>& reconstruct branches
        LocalDB->>LegacyDB: Backup db.json
        LocalDB->>LocalDB: Log migration success
        end
    else No migration needed
        LocalDB->>LocalDB: Continue with existing DB
    end
    
    Init->>LocalDB: console.log(localDb ready)
    App->>App: Routers now use localDb<br/>for all CRUD operations
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes


Possibly related PRs

  • new desktop #101 — Introduces and modifies the desktop persistence layer with the new drizzle/better-sqlite3 local-db package and updates desktop code to use the same localDb/Drizzle APIs.
  • feat(desktop): replace lowdb with SQLite for local database #477 — Makes the same code-level migration from lowdb in-memory JSON to @superset/local-db SQLite + Drizzle and updates imports/usages accordingly across desktop routers.
  • right click menu on workspace item #159 — Modifies the same worktree utility (apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts), where this PR rewrites it to use localDb/drizzle and changes function signatures.

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title 'chore(desktop): bump version to 0.0.34' accurately describes the main visible change in the changeset—the desktop app version bump from 0.0.33 to 0.0.34 in package.json. However, this is misleading as the underlying work is a major migration from lowdb to SQLite with Drizzle ORM, which is far more significant than the version bump. Update the title to reflect the actual scope of changes, such as 'chore(desktop): migrate local database to SQLite with Drizzle ORM' to better communicate the substantial refactoring work.
Description check ⚠️ Warning The PR description is minimal and incomplete. It only states that the version was bumped and that the PR was automatically created by a release script. It does not follow the template structure, lacks details about the substantial database migration work, and provides no context about the purpose or impact of the changes. Expand the description to include a comprehensive summary of the database migration from lowdb to SQLite, explain the addition of Drizzle ORM and better-sqlite3, detail the schema migration logic, and address testing changes and potential breaking changes.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

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.

@github-actions
Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) View Branch
Vercel API (Vercel) Open Preview
Vercel Web (Vercel) Open Preview
Vercel Marketing (Vercel) Open Preview
Vercel Admin (Vercel) Open Preview
Vercel Docs (Vercel) Open Preview

Preview updates automatically with new commits

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (9)
apps/desktop/src/lib/trpc/routers/external/index.ts (1)

58-65: Consider error handling for database operations.

The database upsert operation has no error handling. While tRPC will catch and wrap any thrown errors, synchronous database failures (e.g., disk full, permission issues) will result in generic 500 errors without helpful context.

🔎 Add try/catch for better error messages
 .mutation(async ({ input }) => {
+  try {
     localDb
       .insert(settings)
       .values({ id: 1, lastUsedApp: input.app })
       .onConflictDoUpdate({
         target: settings.id,
         set: { lastUsedApp: input.app },
       })
       .run();
+  } catch (error) {
+    console.error('[external] Failed to save lastUsedApp:', error);
+    throw new Error('Failed to save application preference');
+  }
   await openPathInApp(input.path, input.app);
 }),
apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts (2)

8-15: Consider adding error handling for database queries.

The getWorktreePath function has no error handling. Database errors (e.g., connection issues, corruption) will throw and potentially crash the main process.

🔎 Add defensive error handling
 export function getWorktreePath(worktreeId: string): string | undefined {
+  try {
     const worktree = localDb
       .select()
       .from(worktrees)
       .where(eq(worktrees.id, worktreeId))
       .get();
     return worktree?.path;
+  } catch (error) {
+    console.error('[worktree] Failed to get worktree path:', error);
+    return undefined;
+  }
 }

8-15: Inconsistent return types for "not found" cases.

getWorktreePath returns string | undefined while getWorkspacePath returns string | null. For consistency and clarity, both should use the same convention for representing "not found."

Consider standardizing on null for "not found" across both functions, or document the rationale for the difference.

Also applies to: 22-43

apps/desktop/src/main/lib/local-db/index.ts (2)

27-70: Complex path resolution logic may be fragile.

The getMigrationsDirectory() function has multiple fallback paths with environment-specific logic. This complexity increases the risk of misconfiguration in different deployment scenarios.

Consider:

  1. Adding debug logging for the resolved path to aid troubleshooting
  2. Testing each branch (packaged, dev, preview, test) explicitly
  3. Failing fast with a clear error if migrations aren't found, rather than silently falling back
🔎 Add debug logging
 function getMigrationsDirectory(): string {
+  const logPath = (source: string, path: string) => {
+    console.log(`[local-db] Migrations path (${source}): ${path}`);
+    return path;
+  };
+
   // Check if running in Electron (app.getAppPath exists)
   const isElectron =
     typeof app?.getAppPath === "function" &&
     typeof app?.isPackaged === "boolean";
 
   if (isElectron && app.isPackaged) {
-    return join(process.resourcesPath, "resources/migrations");
+    return logPath("packaged", join(process.resourcesPath, "resources/migrations"));
   }
   
   // ... add logging to other branches

216-216: Consider async initialization pattern for database.

The legacy migration runs synchronously at module load time, blocking the main process startup. For large databases, this could cause noticeable delays. Consider moving database initialization to an async function called during app startup with a loading indicator.

This is not critical for the current PR but could improve user experience in a future refactor.

apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2)

304-310: Consider batch update for tab order shifts.

The loop updates each workspace's tabOrder individually. For small workspace counts this is fine, but if performance becomes a concern, consider using a raw SQL update with increment expression.


1179-1190: N+1 query pattern is acceptable for typical project sizes.

Each worktree triggers a separate query to find its workspace. For the expected small number of worktrees per project, this is fine. Consider using a join if this becomes a performance concern with larger datasets.

apps/desktop/src/lib/trpc/routers/projects/projects.ts (2)

532-538: Unusual query pattern: tautological where clause.

The condition eq(projects.tabOrder, projects.tabOrder) is always true for non-null values. This then requires filtering in JS (line 537). Consider using isNotNull(projects.tabOrder) directly in the query for clarity and to push filtering to the database.

🔎 Suggested fix
 			const activeProjects = localDb
 				.select()
 				.from(projects)
-				.where(eq(projects.tabOrder, projects.tabOrder)) // Just get all with non-null tabOrder
+				.where(isNotNull(projects.tabOrder))
 				.all()
-				.filter((p) => p.tabOrder !== null)
 				.sort((a, b) => (a.tabOrder ?? 0) - (b.tabOrder ?? 0));

Note: You'll need to import isNotNull from drizzle-orm (it's already used in workspaces.ts).


622-629: Inconsistent settings update pattern.

This uses localDb.update(settings).set(...).where(...) directly, while other routers use insert(...).onConflictDoUpdate(...). If the settings row doesn't exist, this update will silently do nothing.

Consider using the same upsert pattern for consistency:

🔎 Suggested fix
-				localDb
-					.update(settings)
-					.set({
-						lastActiveWorkspaceId: remainingWorkspaces[0]?.id ?? null,
-					})
-					.where(eq(settings.id, 1))
-					.run();
+				localDb
+					.insert(settings)
+					.values({ id: 1, lastActiveWorkspaceId: remainingWorkspaces[0]?.id ?? null })
+					.onConflictDoUpdate({
+						target: settings.id,
+						set: { lastActiveWorkspaceId: remainingWorkspaces[0]?.id ?? null },
+					})
+					.run();
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33dbe99 and 6c2ef2e.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (44)
  • apps/admin/package.json
  • apps/admin/src/proxy.ts
  • apps/desktop/electron-builder.ts
  • apps/desktop/electron.vite.config.ts
  • apps/desktop/package.json
  • apps/desktop/scripts/copy-native-modules.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/src/lib/trpc/routers/external/index.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.test.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/db/index.ts
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/test-setup.ts
  • packages/db/src/index.ts
  • packages/local-db/drizzle.config.ts
  • packages/local-db/drizzle/0000_initial_schema.sql
  • packages/local-db/drizzle/meta/0000_snapshot.json
  • packages/local-db/drizzle/meta/_journal.json
  • packages/local-db/package.json
  • packages/local-db/src/index.ts
  • packages/local-db/src/schema/index.ts
  • packages/local-db/src/schema/relations.ts
  • packages/local-db/src/schema/schema.ts
  • packages/local-db/src/schema/zod.ts
  • packages/local-db/tsconfig.json
💤 Files with no reviewable changes (4)
  • packages/db/src/index.ts
  • apps/desktop/src/main/lib/db/schemas.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.test.ts
  • apps/desktop/src/main/lib/db/index.ts
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid using any type in TypeScript - maintain type safety unless absolutely necessary

Files:

  • packages/local-db/src/schema/relations.ts
  • packages/local-db/src/index.ts
  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/electron.vite.config.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • packages/local-db/src/schema/index.ts
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • packages/local-db/src/schema/schema.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • packages/local-db/src/schema/zod.ts
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/test-setup.ts
  • apps/admin/src/proxy.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/lib/trpc/routers/external/index.ts
  • apps/desktop/scripts/copy-native-modules.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • packages/local-db/drizzle.config.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/main/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix

Files:

  • packages/local-db/src/schema/relations.ts
  • packages/local-db/src/index.ts
  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/electron.vite.config.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • packages/local-db/src/schema/index.ts
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • packages/local-db/src/schema/schema.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • packages/local-db/src/schema/zod.ts
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/test-setup.ts
  • apps/admin/src/proxy.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/lib/trpc/routers/external/index.ts
  • apps/desktop/scripts/copy-native-modules.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • packages/local-db/drizzle.config.ts
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/main/index.ts
apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/main/index.ts
apps/desktop/src/main/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Accept object parameters in IPC handlers - do not use positional parameters in ipcMain.handle()

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/main/index.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
Use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/main/lib/notification-sound.ts
  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/electron.vite.config.ts
  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • apps/desktop/src/lib/trpc/routers/settings/index.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/electron-builder.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/test-setup.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/lib/trpc/routers/external/index.ts
  • apps/desktop/scripts/copy-native-modules.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/main/index.ts
**/{components,features}/**/*.{ts,tsx,test.ts,test.tsx,stories.tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Co-locate component dependencies (utils, hooks, constants, config, tests, stories) next to the file using them

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)

Files:

  • apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
**/{components,features}/**/[!.]*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Organize project structure with one folder per component: ComponentName/ComponentName.tsx with index.ts barrel export

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
**/*.{tsx,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use React + TailwindCSS v4 + shadcn/ui for UI development

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
**/{components,features}/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/{components,features}/**/*.tsx: Nest components in parent's components/ folder if used only once, promote to highest shared parent's components/ if used 2+ times
Use one component per file - do not combine multiple components in a single file

Files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
apps/desktop/src/main/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Load environment variables in src/main/index.ts and electron.vite.config.ts with override: true before other imports

Files:

  • apps/desktop/src/main/index.ts
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to packages/db/src/**/*.{ts,tsx} : Store database schema in packages/db/src/ and use Drizzle ORM for schema management
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/api/src/**/*.{ts,tsx} : Use Drizzle ORM for all database operations
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to packages/db/src/**/*.{ts,tsx} : Store database schema in packages/db/src/ and use Drizzle ORM for schema management

Applied to files:

  • packages/local-db/src/schema/relations.ts
  • packages/local-db/src/index.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • packages/local-db/src/schema/index.ts
  • packages/local-db/package.json
  • packages/local-db/src/schema/schema.ts
  • packages/local-db/drizzle/0000_initial_schema.sql
  • packages/local-db/src/schema/zod.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • packages/local-db/tsconfig.json
  • apps/admin/src/proxy.ts
  • packages/local-db/drizzle/meta/0000_snapshot.json
  • apps/admin/package.json
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts
  • packages/local-db/drizzle.config.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/api/src/**/*.{ts,tsx} : Use Drizzle ORM for all database operations

Applied to files:

  • packages/local-db/src/schema/relations.ts
  • apps/desktop/src/lib/trpc/routers/config/config.ts
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/lib/local-db/index.ts
  • apps/desktop/src/lib/trpc/routers/changes/branches.ts
  • packages/local-db/package.json
  • packages/local-db/src/schema/schema.ts
  • packages/local-db/tsconfig.json
  • apps/admin/src/proxy.ts
  • apps/admin/package.json
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
  • packages/local-db/drizzle.config.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/src/lib/trpc/routers/terminal/terminal.ts
  • apps/desktop/src/main/windows/main.ts
  • apps/desktop/test-setup.ts
  • apps/desktop/src/lib/trpc/routers/external/index.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules in renderer process or shared code - use only in main process (src/main/)

Applied to files:

  • apps/desktop/src/lib/trpc/routers/external/helpers.ts
  • apps/desktop/electron.vite.config.ts
  • apps/desktop/scripts/copy-native-modules.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
  • apps/desktop/src/main/index.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/main/index.ts : Load environment variables in src/main/index.ts and electron.vite.config.ts with override: true before other imports

Applied to files:

  • apps/desktop/electron.vite.config.ts
  • apps/desktop/src/main/index.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Create database migrations by modifying Drizzle schema in packages/db/src/schema and running drizzle-kit generate with snake_case migration names

Applied to files:

  • packages/local-db/drizzle/0000_initial_schema.sql
  • packages/local-db/drizzle/meta/0000_snapshot.json
  • packages/local-db/drizzle.config.ts
📚 Learning: 2025-12-21T04:39:28.543Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-12-21T04:39:28.543Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Use alias as defined in `tsconfig.json` when possible

Applied to files:

  • packages/local-db/tsconfig.json
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx
  • apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to apps/desktop/src/{main,renderer,preload}/**/*.{ts,tsx} : Use type-safe IPC communication - define channel types in apps/desktop/src/shared/ipc-channels.ts before implementing handlers

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/test-setup.ts
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to src/components/{ui,ai-elements,react-flow}/**/*.tsx : Use kebab-case single files for shadcn/ui components in src/components/ui/, src/components/ai-elements, and src/components/react-flow/ directories

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx
📚 Learning: 2025-12-18T23:19:10.415Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T23:19:10.415Z
Learning: Applies to **/*.{tsx,css} : Use React + TailwindCSS v4 + shadcn/ui for UI development

Applied to files:

  • apps/desktop/package.json
🧬 Code graph analysis (12)
packages/local-db/src/schema/relations.ts (1)
packages/local-db/src/schema/schema.ts (3)
  • projects (15-40)
  • worktrees (48-70)
  • workspaces (78-109)
apps/desktop/src/lib/trpc/routers/config/config.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (1)
  • projects (15-40)
apps/desktop/src/main/lib/local-db/index.ts (2)
apps/desktop/src/main/lib/app-environment.ts (2)
  • DB_PATH (8-8)
  • SUPERSET_HOME_DIR (5-5)
packages/local-db/src/schema/schema.ts (4)
  • projects (15-40)
  • worktrees (48-70)
  • workspaces (78-109)
  • settings (117-128)
apps/desktop/src/lib/trpc/routers/changes/branches.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (1)
  • worktrees (48-70)
packages/local-db/src/schema/schema.ts (3)
packages/local-db/src/schema/zod.ts (5)
  • GitStatus (12-12)
  • GitHubStatus (48-48)
  • WorkspaceType (68-68)
  • ExternalApp (97-97)
  • TerminalPreset (61-61)
apps/desktop/src/lib/trpc/routers/external/helpers.ts (1)
  • ExternalApp (97-97)
apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts (1)
  • TerminalPreset (3-3)
packages/local-db/src/schema/zod.ts (2)
apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts (1)
  • TerminalPreset (3-3)
apps/desktop/src/lib/trpc/routers/external/helpers.ts (2)
  • EXTERNAL_APPS (97-97)
  • ExternalApp (97-97)
apps/desktop/src/main/windows/main.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (2)
  • workspaces (78-109)
  • worktrees (48-70)
apps/desktop/src/lib/trpc/routers/projects/projects.ts (4)
packages/local-db/src/schema/schema.ts (4)
  • SelectProject (43-43)
  • projects (15-40)
  • workspaces (78-109)
  • settings (117-128)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
apps/desktop/src/lib/trpc/routers/projects/utils/colors/colors.ts (1)
  • assignRandomColor (3-7)
apps/desktop/src/lib/trpc/routers/projects/utils/colors/index.ts (1)
  • assignRandomColor (1-1)
apps/desktop/src/lib/trpc/routers/external/index.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (1)
  • settings (117-128)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (5)
  • projects (15-40)
  • worktrees (48-70)
  • workspaces (78-109)
  • settings (117-128)
  • SelectWorktree (73-73)
apps/desktop/src/lib/trpc/routers/workspaces/utils/worktree.ts (2)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
packages/local-db/src/schema/schema.ts (3)
  • worktrees (48-70)
  • SelectWorkspace (112-112)
  • projects (15-40)
apps/desktop/src/main/index.ts (1)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (80-80)
⏰ 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). (7)
  • GitHub Check: Deploy Marketing
  • GitHub Check: Deploy Web
  • GitHub Check: Deploy Admin
  • GitHub Check: Deploy API
  • GitHub Check: Deploy Docs
  • GitHub Check: Build
  • GitHub Check: Build - macOS (arm64)
🔇 Additional comments (62)
packages/local-db/tsconfig.json (1)

1-11: LGTM! Well-configured TypeScript setup for the local-db package.

The configuration properly:

  • Extends the shared internal package config for consistency
  • Defines a path alias @/* for cleaner imports
  • Includes the Drizzle config file for type checking
  • Follows standard TypeScript and monorepo conventions

This aligns well with the migration to SQLite and Drizzle ORM.

apps/admin/package.json (2)

28-28: No action needed. The drizzle-orm version 0.45.1 is the latest stable release with no known direct vulnerabilities.


28-28: No action needed. Version 0.45.1 is the latest version of drizzle-orm and no direct vulnerabilities have been found for this package. The dependency addition is consistent with the monorepo architecture where multiple packages (apps/api, apps/desktop, packages/local-db, packages/trpc) maintain direct drizzle-orm dependencies alongside the centralized schema management in @superset/db.

Likely an incorrect or invalid review comment.

apps/admin/src/proxy.ts (1)

2-2: Import paths updated correctly for Drizzle ORM migration.

The changes properly separate the database client from schema definitions by importing db from @superset/db/client and users from @superset/db/schema. The direct import of eq from drizzle-orm follows Drizzle best practices, and the relational query syntax (db.query.users.findFirst()) is correctly implemented with full type safety.

apps/desktop/scripts/copy-native-modules.ts (1)

19-19: LGTM! Proper native module support added for better-sqlite3.

The addition of "better-sqlite3" to the NATIVE_MODULES array correctly ensures that the SQLite native module is properly packaged by electron-builder, which is essential for the local database migration.

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/components/CheckItemRow/CheckItemRow.tsx (1)

1-1: LGTM! Type import correctly updated to local-db package.

The import source update aligns with the migration to the centralized @superset/local-db package for all database-related types.

apps/desktop/src/renderer/screens/main/components/SettingsView/PresetsSettings/types.ts (1)

1-1: LGTM! Type import correctly migrated.

Consistent with the broader migration to use @superset/local-db as the central source for database types.

packages/local-db/drizzle.config.ts (1)

3-7: LGTM! Drizzle configuration properly set up.

The configuration correctly points to the schema file and sets up SQLite dialect for the local database. This aligns with the established pattern of using Drizzle ORM for schema management.

Based on learnings, this follows the recommended approach for database schema management.

packages/local-db/drizzle/0000_initial_schema.sql (1)

1-55: LGTM! Well-structured initial schema migration.

The migration properly establishes:

  • Four core tables with appropriate columns and constraints
  • Foreign key relationships with cascade deletion for data integrity
  • Indexes on frequently queried fields for performance
  • Settings table uses a singleton pattern (id DEFAULT 1) which is appropriate for global application settings

Based on learnings, this follows the recommended approach for creating database migrations with Drizzle.

apps/desktop/src/lib/trpc/routers/changes/branches.ts (1)

64-87: LGTM! Clean migration to Drizzle ORM.

The database access has been correctly migrated from in-memory storage to SQLite with Drizzle ORM:

  • Query pattern using select().from().where().get() is idiomatic Drizzle
  • Update pattern using update().set().where().run() is correct
  • The gitStatus handling properly preserves existing status while updating the branch, or sets to null if no prior status exists

Based on learnings, this follows the recommended approach for using Drizzle ORM for all database operations.

packages/local-db/src/schema/zod.ts (1)

1-97: LGTM! Comprehensive and well-structured Zod schemas.

The schema definitions are well-organized with:

  • Clear JSDoc comments for each domain entity
  • Proper Zod validation patterns (enums, objects, arrays, optional fields)
  • Type-safe inference using z.infer<typeof schema>
  • EXTERNAL_APPS constant correctly typed with as const for literal type narrowing

These schemas provide strong runtime validation and TypeScript type safety for the local database layer.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/WorkspaceFooter/components/WorkspaceFooterRight/WorkspaceFooterRight.tsx (1)

1-1: LGTM! Type import correctly updated.

The ExternalApp type import has been properly migrated to @superset/local-db, maintaining type safety while aligning with the centralized schema package.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx (1)

1-1: LGTM! Type import successfully migrated to local-db package.

The import path update for TerminalPreset is consistent with the broader migration to the @superset/local-db package. The type usage throughout the component remains unchanged.

apps/desktop/src/renderer/components/OpenInButton/OpenInButton.tsx (1)

1-1: LGTM! Type import migrated correctly.

The ExternalApp type import has been successfully updated to use the new @superset/local-db package. No runtime behavior changes.

apps/desktop/src/lib/trpc/routers/external/helpers.ts (1)

3-3: LGTM! Import and re-export updated correctly.

Both the EXTERNAL_APPS constant and ExternalApp type have been migrated to @superset/local-db. The re-export at line 97 maintains compatibility for existing consumers.

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksSummary/ChecksSummary.tsx (1)

1-1: LGTM! Type import updated correctly.

The CheckItem type import has been successfully migrated to the @superset/local-db package.

packages/local-db/src/index.ts (1)

1-1: LGTM! Barrel export correctly established.

The barrel export provides a clean entry point for the @superset/local-db package, allowing consumers to import schema types and entities directly from the package root.

apps/desktop/src/lib/trpc/routers/workspaces/utils/github/github.ts (1)

3-3: LGTM! Type imports migrated successfully.

Both CheckItem and GitHubStatus types have been correctly updated to import from @superset/local-db. No runtime behavior changes.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/TabsCommandDialog/index.tsx (1)

1-1: LGTM! Type import updated correctly.

The TerminalPreset type import has been successfully migrated to @superset/local-db.

packages/local-db/drizzle/meta/_journal.json (1)

1-13: LGTM! Standard Drizzle migration journal.

This is a properly formatted Drizzle migration journal file that tracks the initial schema migration. The file is auto-generated and follows the standard Drizzle metadata format.

apps/desktop/electron-builder.ts (2)

36-40: LGTM! Native module unpacking configured correctly.

Adding better-sqlite3 to asarUnpack follows the same pattern as node-pty and is required for native modules to function properly in the packaged Electron app.


50-63: LGTM! Build configuration for migrations and native modules.

The copy rules correctly handle:

  1. Database migrations from the Vite build output to the packaged resources
  2. The better-sqlite3 native module following the same pattern as node-pty
packages/local-db/src/schema/index.ts (1)

1-3: LGTM! Clean barrel export for schema module.

Standard pattern for consolidating public exports. Aligns with the coding guidelines for Drizzle ORM schema management.

apps/desktop/src/main/index.ts (1)

10-15: LGTM! Database initialization via import side-effect.

The localDb import triggers synchronous SQLite initialization (schema migrations + legacy data import). The console.log serves dual purposes: confirming database readiness and preventing the import from being tree-shaken.

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/WorkspaceHoverCard/components/ChecksList/ChecksList.tsx (1)

1-1: LGTM! Type import migrated to centralized package.

The type-only import from @superset/local-db is safe for renderer code since types are erased at compile time—no Node.js runtime dependency is introduced.

apps/desktop/src/lib/trpc/routers/terminal/terminal.ts (3)

3-6: LGTM! Imports updated for Drizzle ORM migration.

Correctly imports the schema tables, eq helper, and localDb instance for the database migration.


53-70: LGTM! Workspace and project lookups migrated to Drizzle.

The queries follow the correct Drizzle pattern: localDb.select().from(table).where(eq(...)).get(). The .get() method appropriately returns a single row or undefined.


178-197: LGTM! Added proper null guard for worktreeId.

Good defensive programming—checking workspace.worktreeId before querying the worktrees table prevents unnecessary queries and potential issues when worktreeId is null (e.g., for non-worktree workspace types).

apps/desktop/src/main/windows/main.ts (2)

2-3: LGTM! Imports updated for Drizzle ORM integration.

Correctly imports schema tables, the eq helper, and the localDb instance.

Also applies to: 8-8


92-106: LGTM! Notification handler migrated to Drizzle queries.

The migration correctly:

  • Guards against missing workspaceId before querying
  • Conditionally fetches the worktree only when workspace.worktreeId exists
  • Preserves the fallback chain for workspaceName
  • Maintains error handling with the existing try-catch block
apps/desktop/src/lib/trpc/routers/config/config.ts (4)

3-5: LGTM! Imports updated for Drizzle ORM migration.

Correctly imports the projects schema, eq helper, and localDb instance.


46-50: LGTM! Query migrated to Drizzle ORM.

Follows the correct pattern for single-row lookups.


66-72: LGTM! Update operation uses correct Drizzle pattern.

The .update().set().where().run() chain is the correct pattern for mutations in Drizzle with better-sqlite3.


79-98: LGTM! Remaining queries migrated consistently.

Both getConfigFilePath and getConfigContent follow the same Drizzle query pattern with proper null handling.

packages/local-db/drizzle/meta/0000_snapshot.json (1)

1-383: LGTM! Drizzle migration snapshot generated correctly.

The schema snapshot properly captures:

  • Tables: projects, settings, workspaces, worktrees with appropriate column types
  • Foreign keys: Cascade deletes configured for referential integrity
  • Indexes: Appropriate indexes on project_id, worktree_id, last_opened_at, branch, and main_repo_path for query optimization
  • Settings singleton: Uses id with default value 1 for single-row configuration

This file is auto-generated by drizzle-kit generate—manual edits should be avoided.

apps/desktop/src/lib/trpc/routers/external/index.ts (1)

84-85: LGTM - Good fallback handling!

The settings read with a sensible default fallback to "cursor" is well-implemented. The optional chaining ensures graceful handling when no settings row exists yet.

apps/desktop/src/main/lib/notification-sound.ts (1)

19-20: LGTM - Well-structured database query with proper fallbacks!

The migration to localDb is clean with appropriate error handling and fallback logic. The optional chaining and null coalescing provide a robust default chain.

packages/local-db/src/schema/relations.ts (1)

1-26: LGTM - Relations correctly mirror the database schema!

The Drizzle ORM relations are properly defined and match the foreign key constraints in the schema. The explicit field-to-reference mappings ensure type safety for joins and relational queries.

packages/local-db/package.json (2)

8-13: TypeScript source exports are correct for workspace-only packages.

The package exports TypeScript source files (.ts) directly, which is appropriate for internal workspace packages that are never published to npm. The consuming packages (desktop app) will transpile these as part of their build.


22-22: No action needed. drizzle-orm 0.45.1 and drizzle-kit 0.31.8 are compatible versions with no known incompatibilities.

apps/desktop/electron.vite.config.ts (2)

50-63: LGTM - Migration copying is properly implemented!

The database migrations are correctly copied from the local-db package to the resources directory with proper cleanup and existence checks. This aligns with the migration path resolution logic in the local-db initialization.


104-104: Good - Native module correctly externalized.

The better-sqlite3 native module is properly externalized, preventing Vite from attempting to bundle it. This is essential for native modules in Electron.

apps/desktop/src/main/lib/local-db/index.ts (2)

92-214: Legacy migration logic is comprehensive and well-structured.

The migrateFromLegacyDb() function properly:

  • Checks for existing data before migrating
  • Handles missing fields with sensible defaults
  • Backs up the original file
  • Has appropriate error handling that doesn't break app startup

The branch reconstruction logic (lines 158-164) for workspaces is particularly good, handling the case where legacy data may be missing the branch field.


74-75: Good choice of WAL mode for SQLite.

Enabling WAL (Write-Ahead Logging) mode improves concurrency and performance, allowing readers to proceed while writes are happening. This is appropriate for an Electron desktop app with multiple potential access points.

apps/desktop/package.json (1)

61-61: Native module packaging for better-sqlite3 is properly configured.

All requirements are already implemented:

  • Module is externalized in electron.vite.config.ts (line 104)
  • ASAR unpacking is configured in electron-builder.ts (line 36) with "**/node_modules/better-sqlite3/**/*"
  • Binary is explicitly included in the packaged app via the files array (lines 59-63)
  • Build strategy properly handles pre-compiled dependencies via npmRebuild: false
apps/desktop/src/lib/trpc/routers/settings/index.ts (3)

12-18: LGTM!

The getSettings() helper correctly ensures a settings row exists before any read/write operation, using an idempotent insert with a fixed id: 1. This is a clean pattern for singleton settings management.


49-56: LGTM!

The upsert pattern using insert().values().onConflictDoUpdate() is idiomatic Drizzle ORM for singleton settings. The in-memory array mutation before persisting is appropriate for this single-user desktop context.


120-147: LGTM!

The self-healing pattern for invalid ringtone IDs is a good defensive approach. It logs a warning for debugging while automatically correcting corrupted state.

apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (6)

121-161: LGTM!

The workspace creation flow correctly:

  1. Inserts the worktree with .returning().get() to capture the new record
  2. Calculates the next tabOrder from existing workspaces
  3. Links the workspace to the worktree via worktreeId

The non-atomic nature of these operations is acceptable for a single-user desktop application.


562-568: LGTM!

The type assertion for workspace.type is necessary since Drizzle infers string from the text column despite the $type<WorkspaceType>() annotation. The explicit interface in groupsMap correctly documents the expected shape.


609-648: LGTM!

The lazy migration pattern for baseBranch correctly distinguishes between:

  • undefined: not yet attempted detection
  • null: attempted but not found (avoids retry)
  • string value: successfully detected

This prevents redundant detection attempts on subsequent calls.


905-910: LGTM!

The explicit deletion of both workspace and worktree records is correct. While the schema defines onDelete: cascade on worktreeId, explicitly deleting both records provides clearer intent and works correctly regardless of deletion order.


1004-1011: LGTM!

Good bounds checking on fromIndex and toIndex before performing the reorder operation.


1330-1331: LGTM!

The close mutation correctly deletes only the workspace record while preserving the worktree. This aligns with the semantic distinction from delete, which removes both the workspace and the underlying git worktree.

apps/desktop/src/lib/trpc/routers/projects/projects.ts (3)

45-75: LGTM!

The upsertProject helper correctly handles both update and insert cases. Returning a manually constructed object on update (line 60) avoids an extra DB query and is safe here since we control exactly what's being updated.


85-142: LGTM!

The extractRepoName utility is well-implemented with:

  • Support for both HTTPS and SSH-style git URLs
  • Defensive validation via SAFE_REPO_NAME_REGEX to prevent path traversal
  • Proper handling of edge cases (percent encoding, trailing slashes, query strings)

596-601: LGTM!

Good use of inArray for bulk deletion of workspaces. This is more efficient than deleting one-by-one in a loop.

apps/desktop/test-setup.ts (1)

65-112: LGTM!

The extended Electron mocks cover additional APIs (clipboard, screen, Notification, Menu) needed for testing. The mock implementations return sensible defaults that won't cause test failures.

packages/local-db/src/schema/schema.ts (4)

15-43: LGTM!

The projects table schema is well-designed with:

  • UUID primary keys for distributed-safe ID generation
  • Appropriate indices on mainRepoPath (for upsert lookups) and lastOpenedAt (for recents sorting)
  • Integer timestamps which are SQLite-optimal
  • Nullable tabOrder to distinguish active vs inactive projects

Based on learnings, this correctly uses Drizzle ORM for schema management.


48-73: LGTM!

The worktrees table correctly:

  • Uses cascading deletes to clean up when parent project is deleted
  • Stores complex gitStatus and githubStatus as JSON columns
  • Includes appropriate indices for projectId and branch lookups

78-112: LGTM!

The workspaces table correctly models the dual-type architecture:

  • worktreeId is nullable to support branch-based workspaces
  • Both FKs have cascading deletes for proper cleanup
  • The $type<WorkspaceType>() annotation provides TypeScript type safety for the type column

117-131: LGTM!

The settings table implements a clean singleton pattern with id: integer().default(1). The JSON storage for terminalPresets is appropriate for the array structure, and the lack of FK on lastActiveWorkspaceId correctly allows the app to handle stale references gracefully.

id: nanoid(),
.mutation(({ input }) => {
const preset: TerminalPreset = {
id: crypto.randomUUID(),
Copy link
Copy Markdown
Contributor

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:

# Search for the settings router file and check its contents
find apps/desktop/src -name "*.ts" -path "*settings*" | head -20

# Also search for uuid package usage in the desktop app
rg -l "uuid" apps/desktop/src --type ts -A 2 -B 2 | head -20

# Check for crypto imports
rg -n "randomUUID|import.*crypto" apps/desktop/src --type ts | head -30

# Check package.json to see if uuid is a dependency
cat package.json | grep -A 20 '"dependencies"' || cat package.json | grep -A 20 '"devDependencies"'

Repository: superset-sh/superset

Length of output: 1335


🏁 Script executed:

head -50 apps/desktop/src/lib/trpc/routers/settings/index.ts

Repository: superset-sh/superset

Length of output: 1388


Add missing crypto import to fix runtime error at line 41.

The file uses crypto.randomUUID() without importing the crypto module. Add import crypto from "node:crypto"; at the top of the file, following the pattern already established in other files like apps/desktop/src/main/lib/auth/auth-service.ts.

🤖 Prompt for AI Agents
In apps/desktop/src/lib/trpc/routers/settings/index.ts around line 41, the code
calls crypto.randomUUID() but the crypto module is not imported; add the import
statement import crypto from "node:crypto"; at the top of the file (following
the existing project pattern) so runtime will have crypto available.

Comment on lines +82 to +84
migrate(localDb, { migrationsFolder });

console.log("[local-db] Migrations complete");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: No error handling for database migrations.

The migrate() call at line 82 has no error handling. If a migration fails (e.g., corrupt migration file, SQL syntax error, file permission issue), the app will crash during startup with an unhandled exception.

🔎 Add error handling for migrations
-migrate(localDb, { migrationsFolder });
-
-console.log("[local-db] Migrations complete");
+try {
+  migrate(localDb, { migrationsFolder });
+  console.log("[local-db] Migrations complete");
+} catch (error) {
+  console.error("[local-db] Migration failed:", error);
+  // Consider: show error dialog to user or create recovery mechanism
+  throw new Error(`Database migration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
+}
📝 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
migrate(localDb, { migrationsFolder });
console.log("[local-db] Migrations complete");
try {
migrate(localDb, { migrationsFolder });
console.log("[local-db] Migrations complete");
} catch (error) {
console.error("[local-db] Migration failed:", error);
// Consider: show error dialog to user or create recovery mechanism
throw new Error(`Database migration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
🤖 Prompt for AI Agents
In apps/desktop/src/main/lib/local-db/index.ts around lines 82 to 84, the
migrate(localDb, { migrationsFolder }) call runs without error handling; wrap
the migration call in a try/catch (and await it if it returns a Promise) so
migration failures are caught, log the full error details via the existing
logger (or console.error) with a clear message, and then handle the failure
deterministically (e.g., clean shutdown with process.exit(1) or rethrow after
logging) to avoid an unhandled exception crashing the app.

Comment on lines +128 to +139
mock.module("main/lib/local-db", () => ({
localDb: {
select: mock(() => ({
from: mock(() => ({
where: mock(() => ({
get: mock(() => null),
all: mock(() => []),
})),
get: mock(() => null),
all: mock(() => []),
})),
})),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Mock may be incomplete: missing orderBy() chain.

The localDb.select().from().orderBy() chain is used in some queries (e.g., workspaces.ts line 932), but the mock doesn't include orderBy. Tests using that pattern will fail.

🔎 Suggested fix
 		select: mock(() => ({
 			from: mock(() => ({
 				where: mock(() => ({
 					get: mock(() => null),
 					all: mock(() => []),
 				})),
+				orderBy: mock(() => ({
+					all: mock(() => []),
+				})),
 				get: mock(() => null),
 				all: mock(() => []),
 			})),
 		})),
📝 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
mock.module("main/lib/local-db", () => ({
localDb: {
select: mock(() => ({
from: mock(() => ({
where: mock(() => ({
get: mock(() => null),
all: mock(() => []),
})),
get: mock(() => null),
all: mock(() => []),
})),
})),
mock.module("main/lib/local-db", () => ({
localDb: {
select: mock(() => ({
from: mock(() => ({
where: mock(() => ({
get: mock(() => null),
all: mock(() => []),
})),
orderBy: mock(() => ({
all: mock(() => []),
})),
get: mock(() => null),
all: mock(() => []),
})),
🤖 Prompt for AI Agents
In apps/desktop/test-setup.ts around lines 128 to 139, the localDb mock defines
select().from().where().get/all and select().from().get/all but is missing an
orderBy() chain used by code (e.g., workspaces.ts line 932); update the mock to
include orderBy() on the same chain levels (i.e., have from() and its returned
object provide an orderBy method that returns an object exposing get and all,
and ensure any nested objects that represent query builders also expose orderBy
chaining) so tests using select().from().orderBy().get/all succeed.

better-sqlite3 uses the `bindings` npm package to locate its native
.node file at runtime. This package (and its dependency file-uri-to-path)
were not being included in the electron-builder output, causing the app
to crash on startup with "Cannot find module 'bindings'" error.

Changes:
- Add bindings and file-uri-to-path to electron-builder files section
- Add both packages to asarUnpack for proper path resolution
- Update copy-native-modules.ts to also handle these dependencies

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Kitenite Kitenite deleted the homely-quail-98f31a branch December 25, 2025 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant