10000 Tauri Desktop App by plyght · Pull Request #6 · R44VC0RP/agenda.dev · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Tauri Desktop App #6

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 3, 2025
Merged

Tauri Desktop App #6

merged 12 commits into from
May 3, 2025

Conversation

plyght
Copy link
Contributor
@plyght plyght commented May 2, 2025

This pull request introduces significant changes to support a desktop-specific build of the application using Tauri. Key updates include the addition of a custom desktop layout and page, configuration adjustments for static and dynamic route handling, and a build system tailored for the Tauri environment. Below are the most important changes grouped by theme:

Desktop Application Support

  • Added DesktopLayout and DesktopApp components to provide a tailored layout and functionality for the desktop version, including custom theming, Tauri integration, and local storage handling for todos. (app/desktop/layout.tsx, app/desktop/page.tsx) [1] [2]
  • Introduced TauriProvider to detect and manage the Tauri environment, enabling desktop-specific features. (components/ui/tauri-provider.tsx)

Build System Enhancements

  • Added build.sh script to streamline the Tauri build process, handle Next.js desktop builds, and provide fallback mechanisms in case of build failures. (build.sh)
  • Created desktop-build.js to generate a minimal Next.js app for the desktop environment, including copying relevant files and customizing the build configuration. (desktop-build.js)

Routing and Configuration Adjustments

  • Updated API route files to explicitly define dynamic and revalidate properties, ensuring compatibility with Next.js static and dynamic route handling. (app/api/auth/[...all]/route.ts, app/api/convert-date/route.ts, and others) (app/api/auth/[...all]/route.tsR2-R5, [1] [2] etc.)
  • Added generateStaticParams function in app/api/auth/[...all]/generateStaticParams.js to support static parameter generation. (app/api/auth/[...all]/generateStaticParams.js) (app/api/auth/[...all]/generateStaticParams.jsR1-R3)

Global Layout Adjustments

  • Integrated TauriProvider into the global layout to enable Tauri-specific functionality across the application. (app/layout.tsx) [1] [2]

These changes collectively enable the application to run as a desktop app with optimized build processes and tailored features for the Tauri environment.

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Introduced desktop application support using Tauri with environment detection and context providers.
    • Added a dedicated desktop layout and page optimized for Tauri, featuring theme and notification support.
    • Implemented a loading screen with automatic redirect for the desktop app entry.
    • Added preference management with safe Tauri API wrappers for desktop settings.
  • Chores

    • Added Tauri configuration files, Rust backend setup, and capability declarations for desktop builds.
    • Updated build scripts and dependencies to support Tauri development, building, and bundling.
    • Adjusted project and build configurations for compatibility with Tauri.
  • Style

    • Updated global and desktop-specific styles for a consistent desktop app appearance.

Copy link
vercel bot commented May 2, 2025

@plyght is attempting to deploy a commit to the exon Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
coderabbitai bot commented May 2, 2025

Warning

Rate limit exceeded

@plyght has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 1 minutes and 46 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 5c54cea and 749b703.

📒 Files selected for processing (1)
  • README.md (2 hunks)

Walkthrough

This set of changes introduces desktop application support using Tauri, integrating both frontend and backend components. New React components, context providers, and hooks are added to detect and adapt to the Tauri environment. A dedicated desktop layout and page are implemented, with logic to handle environment-specific behavior and state management. On the backend, a Rust-based Tauri project is established, including configuration, storage management, commands, and build scripts. The Next.js configuration is updated to support Tauri builds, and new scripts and dependencies are added to package.json. A loading HTML page and Tauri API abstraction are also introduced for seamless desktop integration. Additionally, several API routes are configured for static rendering with disabled revalidation.

Changes

File(s) Change Summary
app/desktop/layout.tsx, app/desktop/page.tsx Added a new desktop layout and page, including context providers, Tauri detection, environment-based redirects, and state management for todos.
app/layout.tsx Wrapped the main theme provider with a new TauriProvider to expose Tauri environment context throughout the app.
components/ui/tauri-provider.tsx Introduced TauriProvider context, a custom hook useTauri, and logic to detect Tauri environment, with global type augmentation.
index.html Added a loading page with a spinner and redirect script for the desktop app.
lib/tauri-api.ts Added a Tauri API abstraction module with environment checks, error handling, and preference management functions.
next.config.mjs Updated configuration to support Tauri builds, including conditional output, distribution directory, rewrites, trailing slash, page extensions, and webpack overrides with Node.js polyfills.
package.json Added Tauri-related scripts and the @tauri-apps/cli development dependency along with Node.js core module polyfill dependencies.
src-tauri/.gitignore Added to ignore build artifacts and generated schemas in the Tauri project directory.
src-tauri/Cargo.toml Introduced a new Rust manifest for the Tauri backend, specifying dependencies and build settings.
src-tauri/build.rs Added a Tauri build script to trigger build steps during compilation.
src-tauri/capabilities/default.json Added a capability definition for default permissions in the Tauri app.
src-tauri/src/desktop_storage.rs Implemented configuration storage logic for desktop app preferences with serialization and error handling.
src-tauri/src/lib.rs Added the main Tauri application entry point with conditional logging setup and commands for preference management.
src-tauri/src/main.rs Added the main function to launch the Tauri app.
src-tauri/tauri.conf.json Added Tauri configuration for build, window, security, and bundling settings.
src-tauri/entitlements.plist Added macOS entitlements plist for app sandboxing and permissions.
tsconfig.json Reordered and added entries in the TypeScript include array for type definitions.
app/api/auth/[...all]/generateStaticParams.js Added a static params generator returning an empty array for auth API routes.
app/api/auth/[...all]/route.ts Configured auth API route for forced dynamic rendering.
app/api/convert-date/route.ts Configured convert-date API route for forced static rendering and disabled revalidation.
app/api/cron/check-reminders/route.ts Configured cron check-reminders API route for forced static rendering and disabled revalidation.
app/api/parse-todo/route.ts Configured parse-todo API route for forced static rendering and disabled revalidation.
app/api/reminders/route.ts Configured reminders API route for forced static rendering and disabled revalidation.
app/api/todos/comments/route.ts Configured todos comments API route for forced static rendering and disabled revalidation.
app/api/todos/route.ts Configured todos API route for forced static rendering and disabled revalidation.
app/api/user/settings/route.ts Configured user settings API route for forced static rendering and disabled revalidation.
app/api/workspaces/personal/route.ts Configured personal workspaces API route for forced static rendering and disabled revalidation.
app/api/workspaces/route.ts Configured workspaces API route for forced static rendering and disabled revalidation.
build.sh Added a build automation script to compile the Tauri desktop app, create macOS app bundle, and generate necessary files.
desktop-build.js Added a custom Bun-based desktop build script to prepare a minimal Next.js desktop app build with environment-specific configs and webpack aliases.
raycast-extension/agenda/* Minor formatting and trailing newline fixes in various Raycast extension files.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DesktopApp (React)
    participant TauriProvider
    participant Tauri API (lib/tauri-api.ts)
    participant Rust Backend

    User->>DesktopApp: Launches desktop app
    DesktopApp->>TauriProvider: Check if running in Tauri
    TauriProvider-->>DesktopApp: isTauri = true/false
    alt isTauri
        DesktopApp->>Tauri API: getPreferences()
        Tauri API->>Rust Backend: invoke("get_preferences")
        Rust Backend-->>Tauri API: Preferences JSON
        Tauri API-->>DesktopApp: Preferences data
        DesktopApp->>User: Render HomeClient with data
    else not Tauri
        DesktopApp->>User: Redirect to root URL
    end
Loading

Poem

In a world of code both sleek and neat,
The desktop rabbit hops to a Tauri beat.
With spinners that twirl and configs that store,
Now Agenda runs on desktops galore!
Rust and React, a partnership true—
Hop, hop, hooray! This build is brand new.
🐇✨


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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

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

Support

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

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

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

CodeRabbit Configuration File (.coderabbit.yaml)

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

Documentation and Community

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

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (13)
src-tauri/.gitignore (1)

1-2: Clarify and standardize comment phrasing.

The comment “will have compiled files and executables” could be rephrased for clarity and consistency. Consider:

-# will have compiled files and executables
+# This directory contains compiled artifacts and executables
src-tauri/src/lib.rs (1)

1-16: Well-implemented Tauri application initialization

The Tauri application setup is properly implemented with:

  1. Appropriate conditional attribute for mobile targets
  2. Smart configuration that only enables logging in debug builds
  3. Standard context generation and builder pattern usage

Consider implementing more graceful error handling instead of using expect, which will crash the application on failure. For a production application, you might want to log the error and either attempt recovery or exit more gracefully with a user-friendly message.

- .run(tauri::generate_context!())
- .expect("error while running tauri application");
+ .run(tauri::generate_context!())
+ .map_err(|e| {
+   eprintln!("Error running application: {}", e);
+   std::process::exit(1);
+ });
index.html (1)

38-41: Immediate redirect may skip loading animation.

The script immediately redirects to the desktop route without any delay, which means users may not see the loading animation at all.

Consider adding a small delay before redirecting to allow the loading animation to be visible:

- // Redirect to the desktop route
- window.location.href = '/desktop';
+ // Redirect to the desktop route after a brief delay to show loading animation
+ setTimeout(() => {
+   window.location.href = '/desktop';
+ }, 800); // 800ms delay

Also consider adding basic error handling in case the redirect fails:

- // Redirect to the desktop route
- window.location.href = '/desktop';
+ // Redirect to the desktop route after a brief delay
+ setTimeout(() => {
+   try {
+     window.location.href = '/desktop';
+   } catch (e) {
+     console.error('Failed to redirect:', e);
+     document.body.innerHTML += '<p>Failed to load. <a href="/desktop">Click here</a> to try again.</p>';
+   }
+ }, 800);
app/desktop/layout.tsx (1)

9-30: Well-structured desktop layout component.

The desktop layout properly defines a complete HTML structure with appropriate metadata and follows the same provider nesting pattern as the main app layout. The suppressHydrationWarning is correctly applied to prevent hydration mismatch errors commonly encountered with theme providers.

There's significant duplication between this layout and the main app/layout.tsx. Consider extracting common layout logic to reduce duplication:

// components/base-layout.tsx
export function BaseLayout({ 
  children, 
  title = 'agenda.dev', 
  description = "the world's most powerful todo list"
}: { 
  children: React.ReactNode;
  title?: string;
  description?: string;
}) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <title>{title}</title>
        <meta name="description" content={description} />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
        />
      </head>
      <body suppressHydrationWarning>
        {children}
      </body>
    </html>
  );
}

// Then in both layouts:
// app/layout.tsx and app/desktop/layout.tsx
export default function SomeLayout({ children }: { children: React.ReactNode }) {
  return (
    <BaseLayout>
      <TauriProvider>
        <ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
          {children}
          <ToastProvider />
        </ThemeProvider>
      </TauriProvider>
    </BaseLayout>
  );
}
app/desktop/page.tsx (1)

1-50: Clean implementation of Tauri desktop integration

The component correctly handles the Tauri environment detection, localStorage data loading, and provides appropriate redirection logic for non-Tauri environments. The loading state is well-managed with a nice spinner UI.

A few suggestions for improvement:

  1. Consider moving the localStorage logic to a custom hook for better separation of concerns and reusability.
  2. Add specific error state handling in the UI rather than just logging to console.
  3. The initialTodos state is always initialized as an empty array, which makes the loading spinner show even when there are no todos to load. Consider setting isLoading to false immediately when not in Tauri environment.
-  const [isLoading, setIsLoading] = useState(true);
+  const [isLoading, setIsLoading] = useState(isTauri);

   // Load todos from localStorage on mount
   useEffect(() => {
     if (isTauri) {
       try {
         const stored = localStorage.getItem('todos');
         if (stored !== null) {
           setInitialTodos(JSON.parse(stored));
         }
       } catch (error) {
         console.error('Failed to load stored todos:', error);
       } finally {
         setIsLoading(false);
       }
+    } else {
+      setIsLoading(false);
     }
-  }, [isTauri]);
+  }, []);
next.config.mjs (1)

17-21: Fix whitespace formatting issue

There's an extra whitespace on line 21.

    // Skip rewrites in Tauri build since they're not supported with static export
    if (process.env.TAURI_ENABLED === 'true') {
      return [];
    }
-    
+<
8000
/span>
🧰 Tools
🪛 ESLint

[error] 21-21: Delete ····

(prettier/prettier)

src-tauri/Cargo.toml (1)

7-7: Empty repository field

The repository field is currently empty. Consider adding the repository URL for better project documentation.

-repository = ""
+repository = "https://github.com/your-org/your-repo"
components/ui/tauri-provider.tsx (2)

15-29: Consider improving the Tauri environment detection

The current implementation checks for Tauri environment only once on mount. While this is typically sufficient, you might consider a more robust approach that could handle dynamic changes in environment status.

useEffect(() => {
  // Check if we're in the Tauri environment
  const checkTauri = () => {
    const isTauriDesktop = process.env.NEXT_PUBLIC_TAURI_DESKTOP === 'true';
    setIsTauri(isTauriDesktop || window.__TAURI__ !== undefined);
  };

  checkTauri();
+ 
+ // Add event listener for potential changes (optional)
+ const handleVisibilityChange = () => {
+   if (!document.hidden) {
+     checkTauri();
+   }
+ };
+ 
+ document.addEventListener('visibilitychange', handleVisibilityChange);
+ return () => {
+   document.removeEventListener('visibilitychange', handleVisibilityChange);
+ };
}, []);

31-36: Consider using a more specific type for __TAURI__

Using any for the __TAURI__ type isn't type-safe. For better type checking and IDE support, consider defining a more specific interface.

declare global {
  interface Window {
-    __TAURI__?: any;
+    __TAURI__?: {
+      invoke: <T = any>(cmd: string, args?: Record<string, unknown>) => Promise<T>;
+      tauri: {
+        invoke: <T = any>(cmd: string, args?: Record<string, unknown>) => Promise<T>;
+      };
+      // Add other Tauri properties as needed
+    };
  }
}
src-tauri/src/desktop_storage.rs (1)

36-43: Consider adding logging for file operations

The save_config function has good error handling, but adding logging would improve debugging capabilities.

pub fn save_config<R: Runtime>(app: &AppHandle<R>, config: &AppConfig) -> Result<(), String> {
    let config_path = get_config_file_path(app);
+    
+    // Log the operation
+    println!("Saving config to {:?}", config_path);
+    
    let config_str = serde_json::to_string_pretty(config)
        .map_err(|e| format!("Failed to serialize config: {}", e))?;
    
    fs::write(config_path, config_str)
        .map_err(|e| format!("Failed to write config file: {}", e))
}
lib/tauri-api.ts (3)

5-53: Simplify the Tauri API initialization logic

The current initialization approach is complex with nested functions and multiple fallbacks. Consider refactoring to a cleaner, more maintainable structure.

let tauriApi: any;

// Only import Tauri API in a browser environment
if (typeof window !== 'undefined') {
  try {
-    // Dynamic import ensures Tauri API is only imported in browser environment
-    const loadTauriApi = async () => {
-      if (window.__TAURI__) {
-        // If Tauri is detected, use its API
-        return {
-          invoke: window.__TAURI__.invoke,
-          ready: true,
-          isTauri: true,
-        };
-      }
-      return {
-        invoke: async () => {
-          console.warn('Tauri not available, API calls will fail');
-          return null;
-        },
-        ready: true,
-        isTauri: false,
-      };
-    };
-
-    tauriApi = {
-      invoke: async (...args: any[]) => {
-        const api = await loadTauriApi();
-        return api.invoke(...args);
-      },
-      isTauri: () => Boolean(window.__TAURI__),
-    };
+    // Directly check for Tauri availability
+    const isTauriAvailable = Boolean(window.__TAURI__);
+    
+    tauriApi = {
+      invoke: async (cmd: string, args?: Record<string, unknown>) => {
+        if (isTauriAvailable) {
+          return window.__TAURI__?.invoke(cmd, args);
+        }
+        console.warn(`Tauri not available, API call to '${cmd}' will fail`);
+        return null;
+      },
+      isTauri: () => isTauriAvailable,
+    };
  } catch (e) {
    console.error('Failed to initialize Tauri API:', e);
    tauriApi = {
      invoke: async () => {
        console.warn('Tauri not available, API calls will fail');
        return null;
      },
      isTauri: () => false,
    };
  }
} else {
  // Server-side rendering fallback
  tauriApi = {
    invoke: async () => null,
    isTauri: () => false,
  };
}

55-64: Add type safety to the getPreferences function

The getPreferences function lacks type information for its return value, which could lead to type errors when used. Consider adding proper TypeScript types.

-export async function getPreferences() {
+export async function getPreferences<T extends Record<string, any> = Record<string, any>>(): Promise<T> {
  if (!tauriApi.isTauri()) return {};
  try {
-    return await tauriApi.invoke('get_preferences');
+    return await tauriApi.invoke<T>('get_preferences');
  } catch (e) {
    console.error('Failed to get preferences:', e);
-    return {};
+    return {} as T;
  }
}

77-84: Remove duplicate type declaration for Window.TAURI

This type declaration is duplicated from components/ui/tauri-provider.tsx. Consider moving it to a shared types file or removing it from one of the locations.

-// Type declaration for the Tauri object
-declare global {
-  interface Window {
-    __TAURI__?: any;
-  }
-}

Consider creating a shared types file like types/tauri.d.ts that both files can import.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b199176 and 81d3846.

⛔ Files ignored due to path filters (2)
  • bun.lockb is excluded by !**/bun.lockb
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (17)
  • app/desktop/layout.tsx (1 hunks)
  • app/desktop/page.tsx (1 hunks)
  • app/layout.tsx (2 hunks)
  • components/ui/tauri-provider.tsx (1 hunks)
  • index.html (1 hunks)
  • lib/tauri-api.ts (1 hunks)
  • next.config.mjs (1 hunks)
  • package.json (2 hunks)
  • src-tauri/.gitignore (1 hunks)
  • src-tauri/Cargo.toml (1 hunks)
  • src-tauri/build.rs (1 hunks)
  • src-tauri/capabilities/default.json (1 hunks)
  • src-tauri/src/desktop_storage.rs (1 hunks)
  • src-tauri/src/lib.rs (1 hunks)
  • src-tauri/src/main.rs (1 hunks)
  • src-tauri/tauri.conf.json (1 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src-tauri/build.rs (1)
src-tauri/src/main.rs (1)
  • main (4-6)
app/layout.tsx (3)
components/ui/tauri-provider.tsx (1)
  • TauriProvider (15-29)
components/theme-provider.tsx (1)
  • ThemeProvider (6-12)
components/toast-provider.tsx (1)
  • ToastProvider (7-50)
app/desktop/layout.tsx (3)
components/ui/tauri-provider.tsx (1)
  • TauriProvider (15-29)
components/theme-provider.tsx (1)
  • ThemeProvider (6-12)
components/toast-provider.tsx (1)
  • ToastProvider (7-50)
app/desktop/page.tsx (2)
components/ui/tauri-provider.tsx (1)
  • useTauri (13-13)
app/HomeClient.tsx (1)
  • HomeClient (50-954)
🪛 ESLint
next.config.mjs

[error] 21-21: Delete ····

(prettier/prettier)

🔇 Additional comments (20)
src-tauri/.gitignore (2)

3-3: Correctly ignore Rust build artifacts.

Using /target/ in this .gitignore properly excludes the src-tauri/target directory produced by Cargo builds.


4-4: Verify generated schema path and regeneration strategy.

Ensure that /gen/schemas is the intended output directory for generated schemas and that you have a build step (or build.rs) to regenerate these files as needed. If schemas are meant to be version-controlled, you may want to remove this ignore rule.

src-tauri/build.rs (1)

1-3: Properly configured Tauri build script

The build script correctly uses tauri_build::build() to handle the Tauri build process during compilation, which is the standard approach for Tauri applications.

src-tauri/src/main.rs (1)

1-6: Correctly structured Tauri application entry point

The main entry point is properly set up with:

  1. The Windows-specific attribute to hide the console window in release mode
  2. A clean separation of concerns by delegating to the app_lib::run() function

This follows Tauri's recommended architecture pattern.

tsconfig.json (1)

25-25: TypeScript configuration updated to support Tauri integration

The configuration now correctly includes the out/types/**/*.ts path, which is necessary for TypeScript to recognize any types generated during the Tauri build process.

app/layout.tsx (2)

9-9: Well-structured Tauri integration with existing providers.

The import of TauriProvider is appropriately placed and follows the component import pattern used throughout the file.


27-32: Clean provider nesting structure.

The TauriProvider is correctly positioned as a wrapper around the ThemeProvider while remaining inside the PostHogProvider. This hierarchy enables components to determine if they're running in a Tauri environment through the context value provided by TauriProvider, while maintaining the existing theme and toast functionality.

src-tauri/capabilities/default.json (1)

1-14:

❓ Verification inconclusive

Appropriate Tauri capability configuration.

The default capabilities configuration follows Tauri's security best practices by explicitly defining the required permissions for the desktop application. The permissions are appropriately scoped to the "main" window only.

Consider reviewing the breadth of file system access granted by "core:path:default" to ensure it meets your security requirements. For production applications, it's recommended to scope filesystem access more narrowly when possible.


🏁 Script executed:

#!/bin/bash
# Check for more specific path permission patterns in Tauri docs
curl -s "https://tauri.app/v1/api/config/#pathaccessscope" | grep -A 10 "allowlist"

Length of output: 81


Review filesystem permission scope in default.json

  • File: src-tauri/capabilities/default.json (lines 1–14)
  • The "core:path:default" permission grants broad filesystem access.

I wasn’t able to locate finer-grained path allowlist scopes in the Tauri docs (the curl | grep check returned no results). Please manually verify whether more specific path access entries exist and narrow this permission to the minimum required for your production use case.

index.html (1)

1-37: Clean loading page design.

The loading page has a well-designed, minimalist UI with appropriate styling for a desktop application. The spinner animation and loading text provide good visual feedback to the user.

app/desktop/layout.tsx (2)

1-8: Appropriate client-side directive and imports.

The 'use client' directive is correctly used as this component will use React hooks via the imported providers. The global styles and provider components are properly imported.


15-18: Consider if the restrictive viewport settings are necessary for desktop.

The viewport meta tag settings with user-scalable=no are typically used for mobile web applications to prevent unwanted scaling. For a desktop application, these restrictions might not be necessary and could potentially limit accessibility.

Are the restrictive viewport settings (user-scalable=no) intentional for the desktop application? For accessibility reasons, it's often better to allow users to scale content if needed, especially in desktop environments.

next.config.mjs (1)

12-15: Good configuration for Tauri static export mode

The configuration correctly sets up Next.js for Tauri by enabling static export mode and adjusting the output directory when the Tauri environment is detected.

package.json (2)

19-23: Well-organized Tauri scripts

The Tauri-related scripts are well-structured, using Bun with a dedicated environment file. The Mac-specific build target is a good addition for cross-platform development.


105-105: Appropriate Tauri dependency

Adding the Tauri CLI as a dev dependency is correct for enabling the Tauri commands.

src-tauri/Cargo.toml (3)

1-9: Well-structured Tauri package configuration

The package metadata is properly configured with all the essential fields for a Rust project. The specified Rust version (1.77.2) ensures compatibility.


13-15: Correct crate configuration for Tauri

The library configuration with multiple crate types (staticlib, cdylib, rlib) is correctly set up to support Tauri's compilation requirements.


17-25:

✅ Verification successful

Appropriate Tauri dependencies

The dependencies are well-chosen for a Tauri application with the necessary components for serialization and logging.

Note that both tauri and tauri-build dependencies have empty feature lists. As development progresses, you might want to enable specific features based on your requirements (e.g., system-tray, dialog, clipboard, etc.).


🌐 Web query:

What are the common Tauri features that might be needed for a desktop todo application?

💡 Result:

Common Tauri Features for a Desktop To-Do Application

Building a desktop to-do application with Tauri leverages the framework’s core strengths: cross-platform support, tight security, native integration, and a lightweight footprint. Here are the most relevant Tauri features you might need for such an app:

Core Features

  • Cross-Platform Support: Tauri enables you to target Windows, macOS, and Linux (and even mobile platforms), distributing your to-do app from a single codebase[1][3][5].
  • Frontend Independence: You can use any web framework (e.g., React, Vue, Svelte) that compiles to HTML, JS, and CSS, making UI development flexible and familiar for web developers[1][3][5][7].
  • Rust-Powered Backend: Use Rust for performant, secure access to system APIs, though for many features you can rely on Tauri’s JavaScript APIs[1][2][5][8].

System Integration Features

  • File System Access: For storing tasks locally, you’ll need access to the file system, available via Tauri’s APIs or through commands defined in Rust and invoked from the frontend[8].
  • Notifications: Tauri offers native system notifications, letting your app remind users of overdue or scheduled tasks[2][4].
  • System Tray Support: For quick access to the app or background operation, you can use the system tray integration, allowing the to-do app to run minimized with menu options or task indicators[2][4].
  • Native Menus and Window Controls: Add custom menus for actions like adding, editing, or clearing tasks, and use Tauri’s window controls for features like minimizing or pinning windows[4][6].
  • < 8000 li>Multiwindow Support: If you want to add pop-out dialogs for task details or settings, Tauri supports managing multiple windows[4].

User Experience Features

  • Icon and Branding Customization: Ship with custom icons for your application across platforms, enhancing professionalism and branding[4].
  • Window Customization: Easily adjust window appearance, size, and behavior to fit the UI style—e.g., custom titlebars or enforced minimum sizes[4].

Development & Productivity

  • Hot Reload and Bundling: Tauri’s development tools support fast iteration with frontend hot-reload and a built-in bundler to generate platform-specific installers (e.g., .exe, .dmg)[2][5].
  • Plugin System: Extend functionality with community or official plugins, such as analytics, logging, state persistence (saving window size/positions), or even database integration[5][8].
  • Security Features: Tauri builds in permissions management, content security policies, and regular security audits, making your app safer by default[1][3][5].

Communication

  • Inter-Process Communication (IPC): Seamlessly connect frontend (JavaScript) and backend (Rust) logic through commands, ideal for triggering data operations or custom actions on user tasks[1][8].

Persistence and Data Storage Options

  • Simple Local Storage: Use the file system API for JSON or use the tauri-plugin-store for a key-value store to persist to-do lists[8].
  • Database Access: For more complex needs, integrate an SQLite backend via tauri-plugin-sql[8].

Summary Table: Tauri Features vs. To-Do App Needs

To-Do App Requirement Tauri Feature/Plugin
Cross-platform Native support for Windows/Mac/Linux[1][3][5]
Responsive UI Any frontend framework that compiles to HTML/CSS/JS[1][3][5][7]
Data persistence File system APIs, tauri-plugin-store, or tauri-plugin-sql[8]
Notifications Native notifications API[2][4]
System tray (background operation) System tray integration[2][4]
Quick access (menus) Native menu APIs[4][6]
Custom icons/branding Icon management API[4]
Window controls Window customization and controls[4]
Sync/advanced storage Plugins for database/storage or custom Rust backend[8]
Security Permissions, CSP, secure IPC, Rust-safety[1][3][5]

Tauri provides all the necessary building blocks for a full-featured, cross-platform desktop to-do application with a modern, web-based user interface and secure, native OS interactions[1][2][3][4][5][8].

Citations:


Enable Essential Tauri Features for a To-Do App

The selected dependencies provide serialization and logging out of the box. As you build your desktop to-do app, consider enabling Tauri features and plugins to support key functionality:

• File System Access
– Enable fs-all or use tauri-plugin-store to persist tasks locally.
• Native Notifications
– Enable notification for reminders and alerts.
• System Tray Integration
– Enable system-tray for background operation and quick-access menus.
• Menus & Shortcuts
– Enable menu and global-shortcut for task actions (add/edit/clear).
• Dialogs
– Enable dialog for file import/export or custom prompts.
• Window Controls & Multiwindow
– Enable window (and multiwindow) for custom titlebars, pop-outs, and branded icons.
• (Optional) Database/State Plugins
– Add tauri-plugin-store for key-value persistence or tauri-plugin-sql for SQLite support.

Example update in src-tauri/Cargo.toml:

[build-dependencies]
tauri-build = { version = "2.2.0", features = [] }

[dependencies]
tauri = { version = "2.5.0", features = [
  "fs-all", "notification", "system-tray",
  "menu", "dialog", "window"
] }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
log = "0.4"
tauri-plugin-log = "2.0.0-rc"
# Optional persistence plugins:
# tauri-plugin-store = "x.y"
# tauri-plugin-sql = "x.y"
components/ui/tauri-provider.tsx (1)

1-14: LGTM! Well-structured React context for Tauri detection

The implementation follows best practices for creating a React context with a custom hook for consuming it. The context is properly exported for use across the application.

src-tauri/src/desktop_storage.rs (1)

1-17: LGTM! Well-structured AppConfig structure with proper default implementation

The AppConfig structure is well-defined and includes a sensible default implementation returning an empty JSON object for preferences.

lib/tauri-api.ts (1)

66-75: LGTM! Well-implemented savePreferences function with proper error handling

The savePreferences function correctly checks for Tauri availability, handles errors properly, and returns appropriate boolean values based on success or failure.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
src-tauri/src/desktop_storage.rs (3)

38-48: Gracefully handle missing permission to create the config directory

fs::create_dir_all can fail due to permission issues.
Right now this bubbles up as CreateDirError but the caller (run() in lib.rs) treats any non-ReadError as a generic failure and keeps running.
Consider making directory-creation failure fatal or at least returning the error to the frontend so the user knows why preferences cannot be saved.


55-60: Use an atomic write to avoid config corruption

A crash or power loss between fs::write opening and closing the file can leave a truncated config.json.
Writing to a temporary file and rename-ing it atomically is safer:

let tmp = config_path.with_extension("json.tmp");
fs::write(&tmp, config_str)?;
fs::rename(tmp, config_path)?;

(Tauri bundles tauri::api::file::write_file which already does this.)


72-76: Surface JSON parse errors separately

serde_json::from_str errors are currently returned as SerializeError, grouped with serialisation failures from save_config.
Creating a dedicated DeserializeError variant improves diagnostics and lets callers decide whether to attempt repair or backup.

 #[derive(Debug, thiserror::Error)]
 pub enum ConfigError {
@@
-    #[error("Failed to serialize config: {0}")]
-    SerializeError(#[from] serde_json::Error),
+    #[error("Failed to serialize config: {0}")]
+    SerializeError(#[from] serde_json::Error),
+
+    #[error("Failed to parse config file: {0}")]
+    DeserializeError(#[from] serde_json::Error),

…and split the From impls accordingly.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 81d3846 and ca45a24.

⛔ Files ignored due to path filters (1)
  • src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (5)
  • src-tauri/Cargo.toml (1 hunks)
  • src-tauri/entitlements.plist (1 hunks)
  • src-tauri/src/desktop_storage.rs (1 hunks)
  • src-tauri/src/lib.rs (1 hunks)
  • src-tauri/tauri.conf.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src-tauri/entitlements.plist
🚧 Files skipped from review as they are similar to previous changes (2)
  • src-tauri/tauri.conf.json
  • src-tauri/Cargo.toml
🧰 Additional context used
🧬 Code Graph Analysis (1)
src-tauri/src/lib.rs (1)
src-tauri/src/desktop_storage.rs (3)
  • load_config (63-77)
  • save_config (55-61)
  • default (13-17)
🔇 Additional comments (1)
src-tauri/src/lib.rs (1)

38-75: Potential compile-time mismatch: app.path() API may not exist

AppHandle::path() was renamed to path_resolver() in Tauri 1.5.
If the project depends on ≥1.5, this will not compile:

let app_data_dir = app.path().app_config_dir()

Please verify the Tauri version and update accordingly:

-let app_data_dir = app.path().app_config_dir()
+let app_data_dir = app.path_resolver().app_config_dir()

Running cargo check will confirm which symbol is available.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
app/api/auth/[...all]/route.ts (1)

10-13: generateStaticParams() has no effect here

generateStaticParams is only invoked for page routes that use dynamic segments.
Including it in a Route Handler is a no-op and may confuse future maintainers. Recommend removing it to reduce dead code.

next.config.mjs (1)

12-18: Address Prettier violations & keep config tidy

The added blank lines are triggering ESLint/Prettier complaints. This quick diff brings the block back in line:

-  
-  // For desktop app, we need to use static export
-  output: process.env.TAURI_ENABLED === 'true' ? 'export' : undefined,
-  
-  // Next will use a different output directory for Tauri builds
-  distDir: process.env.TAURI_ENABLED === 'true' ? 'out' : '.next',
-  
+  // For the desktop build we switch to static export mode
+  output: process.env.TAURI_ENABLED === 'true' ? 'export' : undefined,
+
+  // Use a different output directory for Tauri builds
+  distDir: process.env.TAURI_ENABLED === 'true' ? 'out' : '.next',

Running pnpm exec prettier --write next.config.mjs (or equivalent) will silence the 20+ formatting errors flagged in static analysis.

🧰 Tools
🪛 ESLint

[error] 12-12: Delete ··

(prettier/prettier)


[error] 15-15: Delete ··

(prettier/prettier)


[error] 18-18: Delete ··

(prettier/prettier)

build.sh (1)

64-74: macOS-only packaging limits cross-platform builds

The script builds a .app bundle manually, which:

  1. Works only on macOS targets.
  2. Duplicates functionality already provided by tauri build --bundle dmg.
  3. Risks missing required entitlements and signing steps.

Consider deferring to the official Tauri CLI:

pnpm tauri:build      # or `cargo tauri build`

That command handles Windows .msi / Linux .deb bundles, icons, signing and versioning in one step, and will reduce maintenance overhead.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR 8000 and between 089180c and fceb53d.

⛔ Files ignored due to path filters (3)
  • dist/Agenda 0.1.0.dmg is excluded by !**/dist/**
  • dist/background.icns is excluded by !**/dist/**
  • dist/background.png is excluded by !**/dist/**, !**/*.png
📒 Files selected for processing (17)
  • app/api/auth/[...all]/generateStaticParams.js (1 hunks)
  • app/api/auth/[...all]/route.ts (1 hunks)
  • app/api/convert-date/route.ts (1 hunks)
  • app/api/cron/check-reminders/route.ts (1 hunks)
  • app/api/parse-todo/route.ts (1 hunks)
  • app/api/reminders/route.ts (1 hunks)
  • app/api/todos/comments/route.ts (1 hunks)
  • app/api/todos/route.ts (1 hunks)
  • app/api/user/settings/route.ts (1 hunks)
  • app/api/workspaces/personal/route.ts (1 hunks)
  • app/api/workspaces/route.ts (1 hunks)
  • build.sh (1 hunks)
  • next.config.mjs (1 hunks)
  • package.json (3 hunks)
  • src-tauri/src/desktop_storage.rs (1 hunks)
  • src-tauri/src/lib.rs (1 hunks)
  • src-tauri/tauri.conf.json (1 hunks)
✅ Files skipped from review due to trivial changes (11)
  • app/api/user/settings/route.ts
  • app/api/todos/route.ts
  • app/api/parse-todo/route.ts
  • app/api/auth/[...all]/generateStaticParams.js
  • app/api/cron/check-reminders/route.ts
  • app/api/reminders/route.ts
  • app/api/convert-date/route.ts
  • app/api/workspaces/route.ts
  • app/api/workspaces/personal/route.ts
  • app/api/todos/comments/route.ts
  • src-tauri/tauri.conf.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • src-tauri/src/lib.rs
  • package.json
  • src-tauri/src/desktop_storage.rs
🧰 Additional context used
🧬 Code Graph Analysis (1)
app/api/auth/[...all]/route.ts (2)
lib/auth.ts (1)
  • auth (26-54)
app/api/auth/[...all]/generateStaticParams.js (1)
  • generateStaticParams (1-3)
🪛 ESLint
next.config.mjs

[error] 12-12: Delete ··

(prettier/prettier)


[error] 15-15: Delete ··

(prettier/prettier)


[error] 18-18: Delete ··

(prettier/prettier)


[error] 20-20: Insert ⏎···

(prettier/prettier)


[error] 21-21: Replace ···· with ········

(prettier/prettier)


[error] 22-22: Insert ····

(prettier/prettier)


[error] 23-23: Replace ········ with ············

(prettier/prettier)


[error] 24-24: Insert ····

(prettier/prettier)


[error] 25-25: Insert ····

(prettier/prettier)


[error] 26-26: Insert ····

(prettier/prettier)


[error] 27-27: Insert ····

(prettier/prettier)


[error] 28-28: Replace ·········· with ··············

(prettier/prettier)


[error] 29-29: Insert ····

(prettier/prettier)


[error] 30-30: Insert ····

(prettier/prettier)


[error] 31-31: Replace ········ with ············

(prettier/prettier)


[error] 32-32: Insert ····

(prettier/prettier)


[error] 33-33: Insert ····

(prettier/prettier)


[error] 34-34: Replace ········ with ············

(prettier/prettier)


[error] 35-35: Replace ······ with ··········

(prettier/prettier)


[error] 36-36: Replace ···· with ········

(prettier/prettier)


[error] 37-37: Replace } with ····}⏎···

(prettier/prettier)


[error] 38-38: Insert ····

(prettier/prettier)


[error] 39-39: Insert ····

(prettier/prettier)


[error] 40-40: Replace pageExtensions:·['js',·'jsx',·'ts',·'tsx'].filter(ext with ····pageExtensions:·['js',·'jsx',·'ts',·'tsx'].filter((ext)

(prettier/prettier)


[error] 41-41: Insert ····

(prettier/prettier)


[error] 42-42: Delete ··

(prettier/prettier)

🔇 Additional comments (1)
build.sh (1)

51-61:

❓ Verification inconclusive

Hard-coded binary name can break the build

cargo build --release will output target/release/<crate-name> where <crate-name> is defined in src-tauri/Cargo.toml.
If the crate is renamed (e.g. agenda_app), the subsequent existence check and cp command will fail.

-# Check if the binary was created
-if [ ! -f "target/release/agenda" ]; then
-  echo "Error: Binary not found. Build failed completely."
-  exit 1
-fi
-
-echo "Binary built successfully at: target/release/agenda"
+# Detect the binary name from Cargo metadata
+BIN_PATH=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].targets[] | select(.kind[] == "bin") | .name' | head -n1)
+if [ -z "$BIN_PATH" ] || [ ! -f "target/release/$BIN_PATH" ]; then
+  echo "Error: binary not found after cargo build"
+  exit 1
+fi
+
+echo "Binary built successfully at: target/release/$BIN_PATH"

Requires jq, which is already used elsewhere in the repo; otherwise fall back to reading package.metadata.tauri.bundle.identifier.


#!/bin/bash
# Search for any usage of jq in the repository
rg -n "jq"

#!/bin/bash
# Verify that jq is already used elsewhere in the repo
rg -n "jq" -n

# Confirm the current build.sh snippet to ensure the hard-coded binary name exists
rg -n "cargo build --release" -n build.sh

#!/bin/bash
# Locate the build script
build_file=$(find . -type f -name build.sh | head -n1)
echo "Found build script at: $build_file"

# Show the snippet around the cargo build step
echo -e "\n--- cargo build snippet ---"
rg -n "cargo build --release" -A5 "$build_file"

# Search for jq usage anywhere in the repository
echo -e "\n--- jq usage ---"
rg -n "jq" .

# Locate the src-tauri Cargo.toml and extract the crate name
cargo_toml=$(find . -path "*/src-tauri/Cargo.toml" | head -n1)
echo -e "\nFound Cargo.toml at: $cargo_toml"
echo -e "\n--- Crate name in Cargo.toml ---"
grep -E '^name\s*=' "$cargo_toml"

Ensure build.sh uses the crate’s actual name instead of hard-coding “agenda”

Using a hard-coded binary name (agenda) will break if the Cargo.toml name field changes. Update lines 51–61 in build.sh to detect the binary via cargo metadata (requires jq), for example:

@@ build.sh:51-61
-# Check if the binary was created
-if [ ! -f "target/release/agenda" ]; then
-  echo "Error: Binary not found. Build failed completely."
-  exit 1
-fi
-
-echo "Binary built successfully at: target/release/agenda"
+# Detect the binary name from Cargo metadata
+BIN_NAME=$(cargo metadata --no-deps --format-version=1 \
+  | jq -r '.packages[0].targets[] | select(.kind[]=="bin") | .name' \
+  | head -n1)
+if [ -z "$BIN_NAME" ] || [ ! -f "target/release/$BIN_NAME" ]; then
+  echo "Error: Binary not found after cargo build"
+  exit 1
+fi
+
+echo "Binary built successfully at: target/release/$BIN_NAME"

• Confirm that jq is available in your CI/dev environment (it’s already used elsewhere)
• If not, consider a fallback (e.g. parse src-tauri/Cargo.toml for name =) to avoid build failures

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
raycast-extension/agenda/README.md (1)

3-3: Fix hyphenation and apostrophe usage for "to-dos".

The term “todo's” is incorrect here: use the hyphenated plural “to-dos” (no apostrophe) to refer to tasks.

Proposed diff:

- Manage your todo's and other tasks with ease.
+ Manage your to-dos and other tasks with ease.
🧰 Tools
🪛 LanguageTool

[grammar] ~3-~3: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: # Agenda Manage your todo's and other tasks with ease.

(TO_DO_HYPHEN)

next.config.mjs (2)

37-52: Well-implemented desktop-specific configuration with redundant environment check.

The desktop-specific settings appropriately handle API routes using both the experimental flag and webpack configuration. However, the environment check on line 47 is redundant since this code block only runs when TAURI_ENABLED === 'true'.

  webpack(cfg) {
-   if (process.env.TAURI_ENABLED === 'true') {
-     cfg.externalsPresets = { ...cfg.externalsPresets, node: false };
-   }
+   cfg.externalsPresets = { ...cfg.externalsPresets, node: false };
    return cfg;
  },

12-52: Consider extracting the repeated environment check to a constant.

The expression process.env.TAURI_ENABLED === 'true' is repeated multiple times throughout the configuration. This could be extracted to improve readability and maintainability.

/** @type {import('next').NextConfig} */
+const isTauriEnabled = process.env.TAURI_ENABLED === 'true';
+
const nextConfig = {
  eslint: {
    ignoreDuringBuilds: true,
  },
  typescript: {
    ignoreBuildErrors: true,
  },
  images: {
    unoptimized: true,
  },
  // For the desktop build we switch to static export mode
-  output: process.env.TAURI_ENABLED === 'true' ? 'export' : undefined,
+  output: isTauriEnabled ? 'export' : undefined,

  // Use a different output directory for Tauri builds
-  distDir: process.env.TAURI_ENABLED === 'true' ? 'out' : '.next',
+  distDir: isTauriEnabled ? 'out' : '.next',
  // Web-only features
-  ...(process.env.TAURI_ENABLED !== 'true'
+  ...(!isTauriEnabled
    ? {
        async rewrites() {
          return [
            // ...
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fceb53d and e4ef4f5.

📒 Files selected for processing (13)
  • app/api/auth/[...all]/route.ts (1 hunks)
  • build.sh (1 hunks)
  • index.html (1 hunks)
  • next.config.mjs (1 hunks)
  • raycast-extension/agenda/CHANGELOG.md (1 hunks)
  • raycast-extension/agenda/README.md (1 hunks)
  • raycast-extension/agenda/eslint.config.js (1 hunks)
  • raycast-extension/agenda/package.json (1 hunks)
  • raycast-extension/agenda/src/add-todo.tsx (2 hunks)
  • raycast-extension/agenda/src/list-todos.tsx (4 hunks)
  • raycast-extension/agenda/src/login.tsx (1 hunks)
  • raycast-extension/agenda/src/types.ts (1 hunks)
  • raycast-extension/agenda/src/utils/api.ts (3 hunks)
✅ Files skipped from review due to trivial changes (8)
  • raycast-extension/agenda/CHANGELOG.md
  • raycast-extension/agenda/package.json
  • raycast-extension/agenda/src/types.ts
  • raycast-extension/agenda/src/login.tsx
  • raycast-extension/agenda/src/add-todo.tsx
  • raycast-extension/agenda/src/list-todos.tsx
  • raycast-extension/agenda/eslint.config.js
  • raycast-extension/agenda/src/utils/api.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/api/auth/[...all]/route.ts
  • index.html
  • build.sh
🧰 Additional context used
🪛 LanguageTool
raycast-extension/agenda/README.md

[grammar] ~3-~3: It appears that a hyphen is missing in the noun “to-do” (= task) or did you mean the verb “to do”?
Context: # Agenda Manage your todo's and other tasks with ease.

(TO_DO_HYPHEN)

🔇 Additional comments (2)
next.config.mjs (2)

12-16: Clean and clear configuration for distinguishing between web and desktop builds.

The approach of conditionally setting output and distDir based on the TAURI_ENABLED environment variable is well-implemented. Using static export mode for desktop builds is appropriate, and specifying the output directory as 'out' aligns with Tauri's expectations.


17-36: Good approach for conditionally applying web-only features.

The configuration correctly isolates web-specific features like PostHog rewrites to only run when not in a Tauri environment. This prevents unnecessary network requests in the desktop application.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (1)
next.config.mjs (1)

38-45: 🛠️ Refactor suggestion

Consider enhancing the page extension filtering approach for desktop builds.

The pageExtensions setting on line 44 doesn't actually exclude API routes as they use the same file extensions. This setting only filters by extension type, not by path.

Consider either:

  1. Using the experimental flag to disable API routes explicitly:
-        // Exclude specific pages from the build
-        pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
+        // Disable API routes in desktop build
+        experimental: {
+          disableGloballyConfiguredRouteHolders: true,
+        },
  1. Or use webpack to ignore the API directory:
         pageExtensions: ['tsx', 'ts', 'jsx', 'js'],
+        // Explicitly ignore API routes folder in desktop builds
+        webpack(config) {
+          // Existing webpack config will be merged
+          config.plugins = config.plugins || [];
+          config.plugins.push(new webpack.IgnorePlugin({
+            resourceRegExp: /\/app\/api\//,
+          }));
🧰 Tools
🪛 ESLint

[error] 42-42: Delete ······

(prettier/prettier)


[error] 45-45: Delete ········

(prettier/prettier)

🧹 Nitpick comments (2)
next.config.mjs (2)

17-17: Fix Prettier formatting issue.

There are extra spaces at the end of this line causing a formatting error.

-  distDir: process.env.TAURI_ENABLED === 'true' ? 'out' : '.next',
+  distDir: process.env.TAURI_ENABLED === 'true' ? 'out' : '.next',
🧰 Tools
🪛 ESLint

[error] 17-17: Delete ··

(prettier/prettier)


68-68: Missing newline at end of file.

Add a newline at the end of the file to comply with Prettier formatting.

-export default nextConfig;
+export default nextConfig;
+
🧰 Tools
🪛 ESLint

[error] 68-68: Insert

(prettier/prettier)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between e4ef4f5 and 062230a.

⛔ Files ignored due to path filters (1)
  • bun.lockb is excluded by !**/bun.lockb
📒 Files selected for processing (6)
  • app/desktop/page.tsx (1 hunks)
  • build.sh (1 hunks)
  • desktop-build.js (1 hunks)
  • next.config.mjs (1 hunks)
  • package.json (3 hunks)
  • src-tauri/tauri.conf.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src-tauri/tauri.conf.json
  • app/desktop/page.tsx
  • build.sh
  • package.json
🧰 Additional context used
🪛 ESLint
next.config.mjs

[error] 17-17: Delete ··

(prettier/prettier)


[error] 42-42: Delete ······

(prettier/prettier)


[error] 45-45: Delete ········

(prettier/prettier)


[error] 68-68: Insert

(prettier/prettier)

🔇 Additional comments (5)
next.config.mjs (3)

12-16: Conditional output configuration for static exports looks good.

The approach for conditionally applying static export settings and a custom build directory based on TAURI_ENABLED environment variable is appropriate for supporting both desktop and web builds.


18-37: Rewrites configuration properly isolated for web-only builds.

Good job separating the web-specific PostHog integration routes from the desktop build, as these external API proxies aren't needed in a desktop context.


46-61: Node.js polyfills configuration looks good.

The webpack configuration correctly provides browser-compatible polyfills for Node.js core modules, which is essential for the desktop environment where these modules might be referenced but not available in the browser context.

desktop-build.js (2)

1-14: Well-structured build script with clear documentation.

The script has a clear purpose and documentation explaining what it does. Using Bun as the runtime is appropriate for this build utility.


254-282: Robust recursive copy implementation.

The copyRecursive function is well implemented with appropriate error handling and warnings for missing source paths.

Copy link
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
desktop-build.js (4)

67-67: Consider handling missing HomeClient.tsx file.

The script attempts to copy 'app/HomeClient.tsx', but there's no error handling if this file is missing. Since this appears to be a critical component for the build, the script should validate its presence.

-copyRecursive('app/HomeClient.tsx', path.join(appDir, 'HomeClient.tsx'));
+try {
+  copyRecursive('app/HomeClient.tsx', path.join(appDir, 'HomeClient.tsx'));
+} catch (error) {
+  console.error('Error: Critical file app/HomeClient.tsx missing:', error.message);
+  process.exit(1);
+}

264-269: Improve error handling in copyRecursive function.

The current implementation logs a warning when a source path doesn't exist but continues execution. This could lead to silent failures if important files are missing.

-function copyRecursive(source, destination) {
+function copyRecursive(source, destination, required = false) {
   const fullSourcePath = path.join(process.cwd(), source);

   if (!fs.existsSync(fullSourcePath)) {
-    console.warn(`Warning: Source path does not exist: ${fullSourcePath}`);
-    return;
+    const message = `Source path does not exist: ${fullSourcePath}`;
+    if (required) {
+      throw new Error(message);
+    } else {
+      console.warn(`Warning: ${message}`);
+      return;
+    }
   }

49-59: Consider adding support for environment-specific configuration.

The current implementation reads from .env.desktop if it exists, which is good. However, it doesn't distinguish between development and production environments.

// Read from a desktop-specific env file if it exists, or create one
+const NODE_ENV = process.env.NODE_ENV || 'development';
+const envFiles = [
+  `.env.desktop.${NODE_ENV}.local`,
+  `.env.desktop.${NODE_ENV}`,
+  `.env.desktop.local`,
+  `.env.desktop`
+];

let envLocal = 'NEXT_PUBLIC_IS_DESKTOP=true\n';
-if (fs.existsSync('.env.desktop')) {
-  envLocal = fs.readFileSync('.env.desktop', 'utf8') + '\n' + envLocal;
+
+// Try to read from each file in order of priority
+let foundEnvFile = false;
+for (const file of envFiles) {
+  if (fs.existsSync(file)) {
+    console.log(`Using environment variables from ${file}`);
+    envLocal = fs.readFileSync(file, 'utf8') + '\n' + envLocal;
+    foundEnvFile = true;
+    break;
+  }
+}

-} else {
+if (!foundEnvFile) {
+  console.log('No environment file found, using default values');
   envLocal = `
# Desktop app environment variables
NEXT_PUBLIC_BETTER_AUTH_BASE_URL=https://agenda.dev
BETTER_AUTH_URL=https://agenda.dev
${envLocal}`;
}

185-191: Use more structured debugging output.

The current debugging output simply logs the directory contents as is, which can be messy and hard to read for directories with many files.

// List the files in the out directory to debug
-console.log('Files in out directory:');
+console.log('Files in out directory:');
try {
-  console.log(fs.readdirSync(outDir));
+  const files = fs.readdirSync(outDir);
+  if (files.length === 0) {
+    console.log('  (directory is empty)');
+  } else {
+    files.forEach(file => console.log(`  - ${file}`));
+  }
} catch (error) {
  console.log('Error reading out directory:', error.message);
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 062230a and b11c195.

📒 Files selected for processing (1)
  • desktop-build.js (1 hunks)

@plyght plyght merged commit 7fa4d0e into R44VC0RP:main May 3, 2025
1 of 2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request May 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant
0