Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,12 @@ export function ChatInput(
const getBadgeIcon = () => {
switch (entityType) {
case "human":
return <UserIcon className="size-3" />;
return <UserIcon className="size-3 shrink-0" />;
case "organization":
return <BuildingIcon className="size-3" />;
return <BuildingIcon className="size-3 shrink-0" />;
case "note":
default:
return <FileTextIcon className="size-3" />;
return <FileTextIcon className="size-3 shrink-0" />;
}
};

Expand Down Expand Up @@ -373,7 +373,9 @@ export function ChatInput(
className="mr-2 bg-white text-black border border-border inline-flex items-center gap-1 hover:bg-white max-w-48"
onClick={onNoteBadgeClick}
>
{getBadgeIcon()}
<div className="shrink-0">
{getBadgeIcon()}
</div>
<span className="truncate">{entityTitle}</span>
</Badge>
)
Expand Down
24 changes: 19 additions & 5 deletions apps/desktop/src/components/settings/views/mcp.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useHypr } from "@/contexts";
import { commands as analyticsCommands } from "@hypr/plugin-analytics";
import { commands, type McpServer } from "@hypr/plugin-mcp";
import { Button } from "@hypr/ui/components/ui/button";
import { Input } from "@hypr/ui/components/ui/input";
Expand All @@ -9,6 +11,7 @@ import { PlusIcon, Trash2Icon } from "lucide-react";
import { useEffect, useState } from "react";

export default function MCP() {
const { userId } = useHypr();
const [servers, setServers] = useState<McpServer[]>([]);
const [newUrl, setNewUrl] = useState("");
const [newHeaderKey, setNewHeaderKey] = useState("");
Expand Down Expand Up @@ -48,7 +51,7 @@ export default function MCP() {
},
});

const handleAddServer = () => {
const handleAddServer = async () => {
if (!newUrl.trim() || isAtMaxLimit) {
return;
}
Expand All @@ -62,10 +65,21 @@ export default function MCP() {
};

const updatedServers = [...servers, newServer];
saveServersMutation.mutate(updatedServers);
setNewUrl("");
setNewHeaderKey("");
setNewHeaderValue("");

try {
await saveServersMutation.mutateAsync(updatedServers);

analyticsCommands.event({
event: "mcp_server_added",
distinct_id: userId,
});

setNewUrl("");
setNewHeaderKey("");
setNewHeaderValue("");
} catch (error) {
console.error("Failed to add MCP server:", error);
}
Comment on lines +69 to +82
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Console logging may leak secrets; also diverges from “No error handling” guideline

Logging error objects here risks printing headerValue (e.g., tokens) from updatedServers. Also, repo guidelines say “No error handling” for ts/tsx—prefer relying on react-query’s onError or sanitized logs.

Apply one of the following diffs.

Option A (preferred per guidelines: drop local try/catch and rely on mutation errors bubbling):

   const handleAddServer = async () => {
     if (!newUrl.trim() || isAtMaxLimit) {
       return;
     }
@@
-    try {
-      await saveServersMutation.mutateAsync(updatedServers);
-
-      analyticsCommands.event({
-        event: "mcp_server_added",
-        distinct_id: userId,
-      });
-
-      setNewUrl("");
-      setNewHeaderKey("");
-      setNewHeaderValue("");
-    } catch (error) {
-      console.error("Failed to add MCP server:", error);
-    }
+    await saveServersMutation.mutateAsync(updatedServers);
+
+    analyticsCommands.event({
+      event: "mcp_server_added",
+      distinct_id: userId,
+    });
+
+    setNewUrl("");
+    setNewHeaderKey("");
+    setNewHeaderValue("");
   };

Option B (if you must keep a guard, sanitize logs to avoid secrets):

-    } catch (error) {
-      console.error("Failed to add MCP server:", error);
-    }
+    } catch {
+      // Intentionally not logging payload to avoid leaking header values
+      console.error("Failed to add MCP server");
+    }
📝 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
try {
await saveServersMutation.mutateAsync(updatedServers);
analyticsCommands.event({
event: "mcp_server_added",
distinct_id: userId,
});
setNewUrl("");
setNewHeaderKey("");
setNewHeaderValue("");
} catch (error) {
console.error("Failed to add MCP server:", error);
}
const handleAddServer = async () => {
if (!newUrl.trim() || isAtMaxLimit) {
return;
}
await saveServersMutation.mutateAsync(updatedServers);
analyticsCommands.event({
event: "mcp_server_added",
distinct_id: userId,
});
setNewUrl("");
setNewHeaderKey("");
setNewHeaderValue("");
};
🤖 Prompt for AI Agents
In apps/desktop/src/components/settings/views/mcp.tsx around lines 69 to 82,
remove the local try/catch that calls console.error (which may leak header
values/tokens) and let the react-query mutation surface errors via its onError
handler (configure saveServersMutation.onError to handle/sanitize logging and
user feedback); if you must keep a local guard, do not log the full error object
— only log a minimal, non-sensitive message (e.g., "Failed to add MCP server")
or error.message and ensure updatedServers or any header values are never
included in logs.

};

const handleToggleServer = (index: number) => {
Expand Down
80 changes: 40 additions & 40 deletions apps/desktop/src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -264,14 +264,14 @@ msgstr "(Optional for localhost)"
msgid "(Optional)"
msgstr "(Optional)"

#. placeholder {0}: disabled ? "Wait..." : "Play again"
#. placeholder {0}: disabled ? "Wait..." : "Play video"
#. placeholder {0}: isViewingTemplate ? "Back" : "Save and close"
#. placeholder {0}: isCompact ? "Go" : "Resume"
#. placeholder {0}: disabled ? "Wait..." : isHovered ? (isCompact ? "Go" : "Resume") : (isCompact ? "End" : "Ended")
#: src/components/settings/views/templates.tsx:217
#: src/components/editor-area/note-header/listen-button.tsx:153
#: src/components/editor-area/note-header/listen-button.tsx:231
#: src/components/editor-area/note-header/listen-button.tsx:253
#: src/components/editor-area/note-header/listen-button.tsx:273
#: src/components/settings/views/templates.tsx:217
msgid "{0}"
msgstr "{0}"
Comment on lines +267 to 276
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Double-check: dynamic placeholder {0} stays translatable across locales

The note here indicates {0} may be values like “Back”, “Save and close”, “Go”, or “Resume”. Since msgid “Save and close” and “Resume” appear removed (marked obsolete elsewhere), ensure the code passes localized strings (e.g., tBack, tSave and close) into {0}; otherwise non-English UIs will show English text.

Run this quick search to verify placeholders are fed with translated strings:


🏁 Script executed:

#!/bin/bash
# Verify whether Back/Save and close/Go/Resume are wrapped by i18n in the call sites
rg -n -C2 -g 'src/**' -e 'templates\.tsx:217' -e 'listen-button\.tsx:(153|231|253|273)' \
  ; rg -n -C2 -g 'src/**' -e 't`Back`|t\\([\'"]Back[\'"]\\)|t`Save and close`|t\\([\'"]Save and close[\'"]\\)|t`Resume`|t\\([\'"]Resume[\'"]\\)|t`Go`|t\\([\'"]Go[\'"]\\)'

Length of output: 353


🏁 Script executed:

#!/bin/bash
# Extract the section around line 217 in templates.tsx
sed -n '200,230p' apps/desktop/src/components/settings/views/templates.tsx

# Extract the section covering lines 153–273 in listen-button.tsx
sed -n '140,300p' apps/desktop/src/components/editor-area/note-header/listen-button.tsx

Length of output: 6664


Ensure dynamic placeholder values are localized

The current usage of <Trans> with a generic {0} placeholder and raw English literals means non-English UIs will still display “Back”, “Save and close”, “Go”, “Resume”, etc. directly. Instead, each branch should call the translation function (or its own <Trans>…</Trans>) so that individual strings become extractable translation keys:

  • In apps/desktop/src/components/settings/views/templates.tsx (around line 217):

    - <Trans>{isViewingTemplate ? "Back" : "Save and close"}</Trans>
    + {isViewingTemplate ? t("Back") : t("Save and close")}

    • Import and initialize useTranslation:

    import { useTranslation } from "react-i18next";
    const { t } = useTranslation();
  • In apps/desktop/src/components/editor-area/note-header/listen-button.tsx (around lines 153 and 231):

    - <Trans>{isCompact ? "Go" : "Resume"}</Trans>
    + {t(isCompact ? "Go" : "Resume")}
  • In the same file (around lines 253 and 273), replace the nested placeholder with explicit translations:

    - <Trans>{disabled ? "Wait..." : isHovered ? (isCompact ? "Go" : "Resume") : (isCompact ? "End" : "Ended")}</Trans>
    + {disabled
    +   ? t("Wait...")
    +   : isHovered
    +     ? t(isCompact ? "Go" : "Resume")
    +     : t(isCompact ? "End" : "Ended")}

This change will generate separate translation entries for each literal, ensuring fully localized labels instead of a single {0} placeholder.

🤖 Prompt for AI Agents
In apps/desktop/src/locales/en/messages.po around lines 267 to 276, the PO entry
shows a single "{0}" placeholder used for multiple English literals; update the
corresponding components so each branch uses a real translation key instead of
passing raw literals as a placeholder. In
apps/desktop/src/components/settings/views/templates.tsx (around line 217)
import and initialize useTranslation and replace the placeholder usage with
calls to t for each label; in
apps/desktop/src/components/editor-area/note-header/listen-button.tsx (around
lines 153, 231, 253, 273) do the same—replace nested/raw strings with t("…")
calls (or separate <Trans> elements) for "Back", "Save and close", "Go",
"Resume", "End", "Ended", etc., so each literal becomes an extractable
translation key and the single "{0}" entry is removed/expanded into individual
translation entries.


Expand All @@ -280,8 +280,8 @@ msgstr "{0}"
msgid "{0} calendars selected"
msgstr "{0} calendars selected"

#: src/components/settings/views/sound.tsx:64
#: src/components/welcome-modal/audio-permissions-view.tsx:82
#: src/components/settings/views/sound.tsx:64
msgid "{buttonText}"
msgstr "{buttonText}"

Expand Down Expand Up @@ -318,9 +318,9 @@ msgstr "<0>Create Note</0>"
msgid "Access granted"
msgstr "Access granted"

#: src/components/settings/views/sound.tsx:44
#: src/components/welcome-modal/audio-permissions-view.tsx:58
#: src/components/welcome-modal/calendar-permissions-view.tsx:50
#: src/components/welcome-modal/audio-permissions-view.tsx:58
#: src/components/settings/views/sound.tsx:44
msgid "Access Granted"
msgstr "Access Granted"

Expand Down Expand Up @@ -398,29 +398,29 @@ msgstr "and {0} more members"
msgid "Anyone with the link can view this page"
msgstr "Anyone with the link can view this page"

#: src/components/settings/components/ai/llm-custom-view.tsx:603
#: src/components/welcome-modal/custom-endpoint-view.tsx:498
#: src/components/settings/components/ai/llm-custom-view.tsx:603
msgid "API Base URL"
msgstr "API Base URL"

#: src/components/settings/components/ai/llm-custom-view.tsx:314
#: src/components/settings/components/ai/llm-custom-view.tsx:409
#: src/components/settings/components/ai/llm-custom-view.tsx:514
#: src/components/settings/components/ai/llm-custom-view.tsx:625
#: src/components/settings/views/integrations.tsx:203
#: src/components/welcome-modal/custom-endpoint-view.tsx:294
#: src/components/welcome-modal/custom-endpoint-view.tsx:361
#: src/components/welcome-modal/custom-endpoint-view.tsx:438
#: src/components/welcome-modal/custom-endpoint-view.tsx:518
#: src/components/settings/views/integrations.tsx:203
#: src/components/settings/components/ai/llm-custom-view.tsx:314
#: src/components/settings/components/ai/llm-custom-view.tsx:409
#: src/components/settings/components/ai/llm-custom-view.tsx:514
#: src/components/settings/components/ai/llm-custom-view.tsx:625
msgid "API Key"
msgstr "API Key"

#: src/components/settings/views/profile.tsx:168
msgid "Apple"
msgstr "Apple"

#: src/components/left-sidebar/notes-list.tsx:269
#: src/components/toolbar/buttons/delete-note-button.tsx:43
#: src/components/left-sidebar/notes-list.tsx:269
msgid "Are you sure you want to delete this note?"
msgstr "Are you sure you want to delete this note?"

Expand Down Expand Up @@ -464,8 +464,8 @@ msgstr "Base URL"
#~ msgid "Billing features are currently under development and will be available in a future update."
#~ msgstr "Billing features are currently under development and will be available in a future update."

#: src/components/settings/components/templates-sidebar.tsx:68
#: src/components/settings/views/templates.tsx:319
#: src/components/settings/components/templates-sidebar.tsx:68
msgid "Built-in Templates"
msgstr "Built-in Templates"

Expand Down Expand Up @@ -601,12 +601,12 @@ msgstr "Connect your Obsidian vault to export notes"
msgid "Contacts Access"
msgstr "Contacts Access"

#: src/components/welcome-modal/audio-permissions-view.tsx:189
#: src/components/welcome-modal/calendar-permissions-view.tsx:153
#: src/components/welcome-modal/custom-endpoint-view.tsx:595
#: src/components/welcome-modal/download-progress-view.tsx:255
#: src/components/welcome-modal/llm-selection-view.tsx:94
#: src/components/welcome-modal/model-selection-view.tsx:94
#: src/components/welcome-modal/llm-selection-view.tsx:94
#: src/components/welcome-modal/download-progress-view.tsx:255
#: src/components/welcome-modal/custom-endpoint-view.tsx:595
#: src/components/welcome-modal/calendar-permissions-view.tsx:153
#: src/components/welcome-modal/audio-permissions-view.tsx:189
msgid "Continue"
msgstr "Continue"

Expand All @@ -630,8 +630,8 @@ msgstr "Control how autonomous the AI enhancement should be."
#~ msgid "Control how creative the AI enhancement should be"
#~ msgstr "Control how creative the AI enhancement should be"

#: src/components/editor-area/note-header/chips/participants-chip.tsx:518
#: src/routes/app.human.$id.tsx:535
#: src/components/editor-area/note-header/chips/participants-chip.tsx:518
msgid "Create"
msgstr "Create"

Expand Down Expand Up @@ -659,8 +659,8 @@ msgstr "Create your first template to get started"
#~ msgid "Current Plan"
#~ msgstr "Current Plan"

#: src/components/settings/views/ai-llm.tsx:671
#: src/components/settings/views/ai-stt.tsx:66
#: src/components/settings/views/ai-llm.tsx:671
msgid "Custom"
msgstr "Custom"

Expand All @@ -676,18 +676,18 @@ msgstr "Custom"
msgid "Custom Vocabulary"
msgstr "Custom Vocabulary"

#: src/components/settings/views/ai-llm.tsx:668
#: src/components/settings/views/ai-stt.tsx:63
#: src/components/settings/views/ai-llm.tsx:668
msgid "Default"
msgstr "Default"

#: src/components/settings/components/ai/llm-view.tsx:149
#~ msgid "Default (llama-3.2-3b-q4)"
#~ msgstr "Default (llama-3.2-3b-q4)"

#: src/components/left-sidebar/notes-list.tsx:336
#: src/components/settings/views/team.tsx:165
#: src/components/settings/views/template.tsx:218
#: src/components/settings/views/team.tsx:165
#: src/components/left-sidebar/notes-list.tsx:336
msgid "Delete"
msgstr "Delete"

Expand Down Expand Up @@ -873,10 +873,10 @@ msgstr "Grant both permissions to continue"
#~ msgid "Help us improve the Hyprnote experience by providing feedback."
#~ msgstr "Help us improve the Hyprnote experience by providing feedback."

#: src/components/individualization-modal/how-heard-view.tsx:33
#: src/components/individualization-modal/industry-view.tsx:63
#: src/components/individualization-modal/org-size-view.tsx:24
#: src/components/individualization-modal/role-view.tsx:24
#: src/components/individualization-modal/org-size-view.tsx:24
#: src/components/individualization-modal/industry-view.tsx:63
#: src/components/individualization-modal/how-heard-view.tsx:33
msgid "Help us tailor your Hyprnote experience"
msgstr "Help us tailor your Hyprnote experience"

Expand Down Expand Up @@ -904,8 +904,8 @@ msgstr "Important Q&As"
#~ msgid "Integration with other apps like Notion and Google Calendar"
#~ msgstr "Integration with other apps like Notion and Google Calendar"

#: src/components/settings/views/integrations.tsx:124
#: src/routes/app.settings.tsx:67
#: src/components/settings/views/integrations.tsx:124
msgid "Integrations"
msgstr "Integrations"

Expand Down Expand Up @@ -1047,22 +1047,22 @@ msgstr "Member"
msgid "Members"
msgstr "Members"

#: src/components/settings/views/sound.tsx:127
#: src/components/welcome-modal/audio-permissions-view.tsx:165
#: src/components/settings/views/sound.tsx:127
msgid "Microphone Access"
msgstr "Microphone Access"

#: src/components/settings/components/ai/llm-custom-view.tsx:334
#: src/components/settings/components/ai/llm-custom-view.tsx:429
#: src/components/settings/components/ai/llm-custom-view.tsx:534
#: src/components/welcome-modal/custom-endpoint-view.tsx:315
#: src/components/welcome-modal/custom-endpoint-view.tsx:382
#: src/components/welcome-modal/custom-endpoint-view.tsx:459
#: src/components/settings/components/ai/llm-custom-view.tsx:334
#: src/components/settings/components/ai/llm-custom-view.tsx:429
#: src/components/settings/components/ai/llm-custom-view.tsx:534
msgid "Model"
msgstr "Model"

#: src/components/settings/components/ai/llm-custom-view.tsx:650
#: src/components/welcome-modal/custom-endpoint-view.tsx:544
#: src/components/settings/components/ai/llm-custom-view.tsx:650
msgid "Model Name"
msgstr "Model Name"

Expand Down Expand Up @@ -1090,8 +1090,8 @@ msgstr "My Templates"
msgid "New note"
msgstr "New note"

#: src/components/left-sidebar/events-list.tsx:181
#: src/components/left-sidebar/notes-list.tsx:313
#: src/components/left-sidebar/events-list.tsx:181
msgid "New window"
msgstr "New window"

Expand Down Expand Up @@ -1187,9 +1187,9 @@ msgstr "Only works with Custom Endpoints. Please configure one of the above firs
msgid "Open finder view"
msgstr "Open finder view"

#: src/components/toolbar/buttons/new-window-button.tsx:35
#: src/components/left-sidebar/search-list.tsx:298
#: src/components/left-sidebar/search-list.tsx:368
#: src/components/toolbar/buttons/new-window-button.tsx:35
msgid "Open in new window"
msgstr "Open in new window"

Expand Down Expand Up @@ -1288,8 +1288,8 @@ msgstr "Recent Notes"
#~ msgid "Remove {0} from list"
#~ msgstr "Remove {0} from list"

#: src/components/settings/views/sound.tsx:61
#: src/components/welcome-modal/audio-permissions-view.tsx:79
#: src/components/settings/views/sound.tsx:61
msgid "Requesting..."
msgstr "Requesting..."

Expand Down Expand Up @@ -1343,8 +1343,8 @@ msgstr "Saving..."
msgid "Search names or emails"
msgstr "Search names or emails"

#: src/components/settings/components/template-list.tsx:43
#: src/components/settings/components/templates-sidebar.tsx:33
#: src/components/settings/components/template-list.tsx:43
msgid "Search templates..."
msgstr "Search templates..."

Expand Down Expand Up @@ -1488,8 +1488,8 @@ msgstr "Summary language"
#~ msgid "Synchronization across multiple devices"
#~ msgstr "Synchronization across multiple devices"

#: src/components/settings/views/sound.tsx:137
#: src/components/welcome-modal/audio-permissions-view.tsx:175
#: src/components/settings/views/sound.tsx:137
msgid "System Audio Access"
msgstr "System Audio Access"

Expand Down Expand Up @@ -1653,8 +1653,8 @@ msgstr "Vault Name"
msgid "View calendar"
msgstr "View calendar"

#: src/components/editor-area/note-header/chips/event-chip.tsx:209
#: src/components/left-sidebar/events-list.tsx:193
#: src/components/editor-area/note-header/chips/event-chip.tsx:209
msgid "View in calendar"
msgstr "View in calendar"

Expand Down Expand Up @@ -1726,7 +1726,7 @@ msgstr "Your LinkedIn username (the part after linkedin.com/in/)"
msgid "Your Name"
msgstr "Your Name"

#: src/components/settings/components/templates-sidebar.tsx:45
#: src/components/settings/views/templates.tsx:255
#: src/components/settings/components/templates-sidebar.tsx:45
msgid "Your Templates"
msgstr "Your Templates"
Loading
Loading