Skip to content

Conversation

@duckduckhero
Copy link
Contributor

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Jul 2, 2025

📝 Walkthrough

Walkthrough

This update introduces a customizable meeting note enhancement system using user-defined templates. It adds a new "templates" settings tab and interface for creating, editing, cloning, and deleting templates, including emoji selection. The enhancement logic now supports template-based custom grammar, and configuration/state management is extended to track the selected template.

Changes

File(s) Change Summary
apps/desktop/src/components/editor-area/index.tsx Extended useEnhanceMutation to support template-based custom grammar, added generateCustomGBNF, and improved prompt metadata.
apps/desktop/src/components/settings/views/templates.tsx Added new TemplatesView component for managing templates (CRUD UI, selection, and persistence).
apps/desktop/src/components/settings/views/template.tsx Enhanced TemplateEditor to support emoji selection, improved title handling, and implemented delete functionality.
apps/desktop/src/components/settings/components/template-sections.tsx Added section deletion, improved drag controls, and refactored UI for template sections.
apps/desktop/src/components/settings/components/tab-icon.tsx,
.../types.ts
Added "templates" tab, icon, and type support.
apps/desktop/src/components/settings/views/index.ts Exported new TemplatesView for routing.
apps/desktop/src/components/settings/views/general.tsx Updated mutation to include selected_template_id in config updates.
apps/desktop/src/routes/app.settings.tsx Integrated "templates" tab and view into settings route.
crates/db-user/src/config_types.rs,
plugins/db/js/bindings.gen.ts
Added selected_template_id to ConfigGeneral struct and type.
crates/template/assets/enhance.system.jinja Updated system prompt template to conditionally include template structure and instructions.
plugins/local-llm/src/server.rs Extended grammar handling to support custom and none grammar options in local LLM server.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SettingsUI
    participant DB
    participant Editor
    participant LLM

    User->>SettingsUI: Open Templates Tab
    SettingsUI->>DB: Fetch templates
    DB-->>SettingsUI: Return templates
    User->>SettingsUI: Create/Edit/Clone/Delete template
    SettingsUI->>DB: Update templates
    DB-->>SettingsUI: Confirm update
    User->>SettingsUI: Select template
    SettingsUI->>DB: Save selected_template_id

    User->>Editor: Trigger Enhance
    Editor->>DB: Fetch config (including selected_template_id)
    Editor->>DB: Fetch selected template (if any)
    Editor->>Editor: Generate custom grammar (if template)
    Editor->>LLM: Send enhance request (with grammar & template info)
    LLM-->>Editor: Return enhanced notes
    Editor-->>User: Display enhanced notes
Loading

Possibly related PRs

  • fastrepl/hyprnote#991: Also modifies useEnhanceMutation in the same file, focusing on diffing pre-meeting and raw notes for input, indicating a related change to enhancement logic.
  • fastrepl/hyprnote#935: Updates useEnhanceMutation to add an onSuccess callback and integrates a separate title-generation mutation, showing related enhancements to AI mutation handling in the same module.
✨ Finishing Touches
  • 📝 Generate Docstrings

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:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 explain this code block.
    • @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 explain its main purpose.
    • @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.

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: 5

🔭 Outside diff range comments (1)
apps/desktop/src/components/settings/components/template-sections.tsx (1)

30-33: Fix state update bug in handleChange.

The handleChange method uses the stale items state when calling onChange, which could lead to data loss when multiple rapid updates occur.

   const handleChange = (item: ReorderItem & { id: string }) => {
-    setItems(items.map((i) => (i.id === item.id ? item : i)));
-    onChange(items);
+    const updatedItems = items.map((i) => (i.id === item.id ? item : i));
+    setItems(updatedItems);
+    onChange(updatedItems);
   };
🧹 Nitpick comments (2)
plugins/local-llm/src/server.rs (1)

235-241: Consider simplifying the metadata access pattern.

The nested unwrap_or calls work but could be simplified for better readability.

Consider extracting the metadata access into a variable to avoid duplication:

-        Some("custom") => request
-            .metadata
-            .as_ref()
-            .unwrap_or(&serde_json::Value::Object(Default::default()))
-            .get("customGrammar")
-            .and_then(|v| v.as_str())
-            .map(|s| s.to_string()),
+        Some("custom") => {
+            let metadata = request.metadata.as_ref()
+                .unwrap_or(&serde_json::Value::Object(Default::default()));
+            metadata.get("customGrammar")
+                .and_then(|v| v.as_str())
+                .map(|s| s.to_string())
+        }
apps/desktop/src/components/editor-area/index.tsx (1)

199-199: Use let instead of var.

For consistency with modern JavaScript standards and the rest of the codebase.

-  var finalInput = "";
+  let finalInput = "";
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6aeeebe and b180037.

📒 Files selected for processing (13)
  • apps/desktop/src/components/editor-area/index.tsx (3 hunks)
  • apps/desktop/src/components/settings/components/tab-icon.tsx (2 hunks)
  • apps/desktop/src/components/settings/components/template-sections.tsx (6 hunks)
  • apps/desktop/src/components/settings/components/types.ts (1 hunks)
  • apps/desktop/src/components/settings/views/general.tsx (1 hunks)
  • apps/desktop/src/components/settings/views/index.ts (1 hunks)
  • apps/desktop/src/components/settings/views/template.tsx (4 hunks)
  • apps/desktop/src/components/settings/views/templates.tsx (1 hunks)
  • apps/desktop/src/routes/app.settings.tsx (3 hunks)
  • crates/db-user/src/config_types.rs (2 hunks)
  • crates/template/assets/enhance.system.jinja (1 hunks)
  • plugins/db/js/bindings.gen.ts (1 hunks)
  • plugins/local-llm/src/server.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.{js,ts,tsx,rs}`: 1. No error handling. 2. No unused imports, variables, or functions. 3. For comments, keep it minimal. It should be about "Why", not "What".

**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • apps/desktop/src/components/settings/views/index.ts
  • apps/desktop/src/components/settings/views/general.tsx
  • plugins/db/js/bindings.gen.ts
  • crates/db-user/src/config_types.rs
  • apps/desktop/src/routes/app.settings.tsx
  • apps/desktop/src/components/settings/components/types.ts
  • apps/desktop/src/components/settings/components/tab-icon.tsx
  • apps/desktop/src/components/settings/views/template.tsx
  • plugins/local-llm/src/server.rs
  • apps/desktop/src/components/editor-area/index.tsx
  • apps/desktop/src/components/settings/views/templates.tsx
  • apps/desktop/src/components/settings/components/template-sections.tsx
🪛 Biome (1.9.4)
apps/desktop/src/components/editor-area/index.tsx

[error] 468-468: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)


[error] 468-468: Unexpected control character in a regular expression.

Control characters are unusual and potentially incorrect inputs, so they are disallowed.

(lint/suspicious/noControlCharactersInRegex)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: ci (windows, windows-latest)
  • GitHub Check: ci (macos, macos-latest)
  • GitHub Check: ci
🔇 Additional comments (15)
crates/db-user/src/config_types.rs (1)

47-47: LGTM! Clean addition of the selected template field.

The new selected_template_id field is properly typed as Option<String> and correctly initialized as None in the default implementation. This follows Rust conventions and integrates seamlessly with the existing configuration structure.

Also applies to: 59-59

apps/desktop/src/components/settings/views/index.ts (1)

12-12: LGTM! Export follows the established pattern.

The new TemplatesView export is consistent with the existing module structure and naming conventions.

apps/desktop/src/components/settings/views/general.tsx (1)

129-129: LGTM! Correctly preserves the selected template ID during updates.

The addition ensures that the selected_template_id is preserved when updating other general configuration fields, following the established pattern for maintaining existing config values.

apps/desktop/src/routes/app.settings.tsx (3)

8-8: LGTM! Import follows the established pattern.

The TemplatesView import is correctly added and follows the existing import structure.


94-95: LGTM! Tab label integration is consistent.

The templates tab label addition maintains the existing conditional rendering chain structure and follows the established pattern for tab labels.


127-127: LGTM! Tab content rendering follows the established pattern.

The conditional rendering for the templates tab is consistent with how other tabs are handled in the component.

plugins/db/js/bindings.gen.ts (1)

154-154: LGTM! Generated type definition correctly reflects backend changes.

The selected_template_id: string | null field correctly maps the Rust Option<String> type to TypeScript, maintaining type safety across the stack.

apps/desktop/src/components/settings/components/tab-icon.tsx (1)

5-5: LGTM! Clean implementation of the templates tab icon.

The changes properly integrate the new templates tab icon while maintaining consistency with other tab icons by using the same styling approach.

Also applies to: 23-23, 25-25, 30-31

apps/desktop/src/components/settings/components/types.ts (1)

2-2: LGTM! Proper integration of the templates tab type.

The changes correctly extend the Tab type and TABS array to support the new templates feature while maintaining consistency with the existing structure.

Also applies to: 4-4, 12-12

crates/template/assets/enhance.system.jinja (1)

3-13: LGTM! Well-structured template customization instructions.

The conditional block properly instructs the assistant to follow custom template structures when provided, maintaining strict adherence to the user-defined format.

apps/desktop/src/components/settings/views/template.tsx (1)

26-174: LGTM! Well-implemented emoji selector feature.

The emoji selection functionality is cleanly implemented with proper Unicode emoji handling, state management, and UI integration. The popover-based selector provides a good user experience.

apps/desktop/src/components/editor-area/index.tsx (2)

447-500: Well-implemented template grammar generation!

The generateCustomGBNF function properly handles edge cases, validates input, escapes special characters, and generates valid GBNF grammar. The control character removal at line 468 is a good security practice.


244-268: Add error handling for template operations.

The template loading and processing logic should handle potential failures gracefully to prevent the enhancement process from breaking.

   if (selectedTemplateId) {
-    const templates = await dbCommands.listTemplates();
-    const selectedTemplate = templates.find(t => t.id === selectedTemplateId);
+    try {
+      const templates = await dbCommands.listTemplates();
+      const selectedTemplate = templates.find(t => t.id === selectedTemplateId);

-    if (selectedTemplate) {
-      // Generate custom GBNF grammar
-      if (selectedTemplate.sections && selectedTemplate.sections.length > 0) {
-        customGrammar = generateCustomGBNF(selectedTemplate.sections);
-      }
+      if (selectedTemplate) {
+        // Generate custom GBNF grammar
+        if (selectedTemplate.sections && selectedTemplate.sections.length > 0) {
+          customGrammar = generateCustomGBNF(selectedTemplate.sections);
+        }

-      // Format template as a readable string for system prompt
-      templateInfo = `
+        // Format template as a readable string for system prompt
+        templateInfo = `
 SELECTED TEMPLATE:
 Template Title: ${selectedTemplate.title || "Untitled"}
 Template Description: ${selectedTemplate.description || "No description"}

 Sections:`;

-      selectedTemplate.sections?.forEach((section, index) => {
-        templateInfo += `
+        selectedTemplate.sections?.forEach((section, index) => {
+          templateInfo += `
   ${index + 1}. ${section.title || "Untitled Section"}
      └─ ${section.description || "No description"}`;
-      });
+        });
+      }
+    } catch (error) {
+      console.error("Failed to load template:", error);
+      // Continue with enhancement without custom template
     }
   }

Likely an incorrect or invalid review comment.

apps/desktop/src/components/settings/views/templates.tsx (1)

300-413: Excellent TemplateCard implementation!

The component properly handles:

  • Emoji extraction and fallback logic
  • Text truncation for long titles/descriptions
  • Clean event handling with stopPropagation for edit button
  • Visual feedback for selected state
apps/desktop/src/components/settings/components/template-sections.tsx (1)

35-39: Well-implemented section deletion functionality!

The delete functionality is properly integrated with:

  • Clean removal from state
  • Proper onChange callback invocation
  • Intuitive UI with hover effects
  • Correct event handling

Also applies to: 116-136

type ViewState = "list" | "editor" | "new";

export default function TemplatesView() {
console.log("templatesview mounted@!");
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove debug console.log statement.

Debug logging should not be committed to production code.

-  console.log("templatesview mounted@!");
📝 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
console.log("templatesview mounted@!");
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx at line 16, remove
the debug console.log statement "templatesview mounted@!" to prevent debug
logging from being included in production code.

Comment on lines +67 to +68
console.log("loaded templates: ", templates);
console.log(templates);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove debug console.log statements.

Debug logging should not be committed to production code.

-      console.log("loaded templates: ", templates);
-      console.log(templates);
📝 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
console.log("loaded templates: ", templates);
console.log(templates);
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx at lines 67 to 68,
remove the debug console.log statements that output the loaded templates. These
debug logs should not be present in production code to keep the console clean
and avoid leaking potentially sensitive information.

Comment on lines +141 to +163
const handleCloneTemplate = async (template: Template) => {
try {
const clonedTemplate: Template = {
...template,
id: crypto.randomUUID(),
title: `${template.title} Copy`,
user_id: userId,
};
await dbCommands.upsertTemplate(clonedTemplate);
await loadTemplates();
} catch (error) {
console.error("Failed to clone template:", error);
}
};

const handleDeleteTemplate = async (template: Template) => {
try {
await dbCommands.deleteTemplate(template.id);
await loadTemplates();
} catch (error) {
console.error("Failed to delete template:", error);
}
};
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add user-facing error notifications.

Template operations should provide feedback to users when they fail, not just log to console.

Consider using a toast notification system to inform users of operation failures:

   const handleCloneTemplate = async (template: Template) => {
     try {
       const clonedTemplate: Template = {
         ...template,
         id: crypto.randomUUID(),
         title: `${template.title} Copy`,
         user_id: userId,
       };
       await dbCommands.upsertTemplate(clonedTemplate);
       await loadTemplates();
     } catch (error) {
       console.error("Failed to clone template:", error);
+      toast({
+        title: "Failed to clone template",
+        description: "Please try again later",
+        variant: "destructive",
+      });
     }
   };

   const handleDeleteTemplate = async (template: Template) => {
     try {
       await dbCommands.deleteTemplate(template.id);
       await loadTemplates();
     } catch (error) {
       console.error("Failed to delete template:", error);
+      toast({
+        title: "Failed to delete template",
+        description: "Please try again later",
+        variant: "destructive",
+      });
     }
   };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleCloneTemplate = async (template: Template) => {
try {
const clonedTemplate: Template = {
...template,
id: crypto.randomUUID(),
title: `${template.title} Copy`,
user_id: userId,
};
await dbCommands.upsertTemplate(clonedTemplate);
await loadTemplates();
} catch (error) {
console.error("Failed to clone template:", error);
}
};
const handleDeleteTemplate = async (template: Template) => {
try {
await dbCommands.deleteTemplate(template.id);
await loadTemplates();
} catch (error) {
console.error("Failed to delete template:", error);
}
};
const handleCloneTemplate = async (template: Template) => {
try {
const clonedTemplate: Template = {
...template,
id: crypto.randomUUID(),
title: `${template.title} Copy`,
user_id: userId,
};
await dbCommands.upsertTemplate(clonedTemplate);
await loadTemplates();
} catch (error) {
console.error("Failed to clone template:", error);
toast({
title: "Failed to clone template",
description: "Please try again later",
variant: "destructive",
});
}
};
const handleDeleteTemplate = async (template: Template) => {
try {
await dbCommands.deleteTemplate(template.id);
await loadTemplates();
} catch (error) {
console.error("Failed to delete template:", error);
toast({
title: "Failed to delete template",
description: "Please try again later",
variant: "destructive",
});
}
};
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/templates.tsx between lines 141
and 163, the error handling for cloning and deleting templates only logs errors
to the console without notifying users. Enhance user experience by integrating a
toast notification system to display error messages when these operations fail.
Modify the catch blocks to trigger user-facing error notifications alongside the
existing console.error calls.

item: ReorderItem & { id: string };
onChange: (item: ReorderItem & { id: string }) => void;
onDelete: (itemId: string) => void;
dragControls: any;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add proper typing for dragControls prop.

Using any type defeats TypeScript's type safety benefits.

-  dragControls: any;
+  dragControls: ReturnType<typeof useDragControls>;

You'll need to import the type:

import { type DragControls, useDragControls } from "motion/react";
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/components/template-sections.tsx at line
96, replace the type of dragControls from 'any' to the proper DragControls type
imported from "motion/react". Import 'DragControls' using `import { type
DragControls } from "motion/react";` and update the dragControls declaration to
use this type to ensure type safety.

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.

3 participants