diff --git a/.gitignore b/.gitignore
index 65ddcaf1c4..0e181a5604 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,6 +36,9 @@ blob-report/
# Node modules (pnpm workspace hoists to root)
node_modules/
+# pnpm content-addressable store (local cache, not portable)
+.pnpm-store/
+
# Root npm lockfiles are accidental; desktop uses pnpm in /desktop.
/package-lock.json
diff --git a/desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx b/desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx
index 8be5f4719b..55e63a8b8f 100644
--- a/desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx
+++ b/desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx
@@ -737,7 +737,7 @@ export function AgentInstanceEditDialog({
// explicitly instead of relying on the user to know the policy.
if (!isManagedAgentActive(result.agent)) {
const startedName = result.agent.name;
- toast(`${startedName} saved while stopped.`, {
+ toast(`Changes saved. ${startedName} is still stopped.`, {
action: {
label: "Start now",
onClick: () => {
@@ -746,8 +746,8 @@ export function AgentInstanceEditDialog({
onError: (error) =>
toast.error(
error instanceof Error
- ? `${startedName} failed to start: ${error.message}`
- : `${startedName} failed to start.`,
+ ? `Couldn't start ${startedName}: ${error.message}`
+ : `Couldn't start ${startedName}`,
),
});
},
diff --git a/desktop/src/features/agents/ui/PersonaDeleteDialog.tsx b/desktop/src/features/agents/ui/PersonaDeleteDialog.tsx
index fd9da43751..f9c3125ae4 100644
--- a/desktop/src/features/agents/ui/PersonaDeleteDialog.tsx
+++ b/desktop/src/features/agents/ui/PersonaDeleteDialog.tsx
@@ -32,16 +32,16 @@ export function personaDeleteDescription(
instanceCount: number,
): string {
if (!persona) {
- return "Delete this agent.";
+ return "This agent will be removed.";
}
if (instanceCount === 0) {
- return `Delete ${persona.displayName}.`;
+ return `${persona.displayName} will be removed.`;
}
const cascade =
instanceCount === 1
- ? "Also deletes 1 agent instance and archives its identity on the relay, so it no longer appears in member lists or mention suggestions."
- : `Also deletes ${instanceCount} agent instances and archives their identities on the relay, so they no longer appear in member lists or mention suggestions.`;
- return `Delete ${persona.displayName}. ${cascade}`;
+ ? "Its 1 agent instance is also deleted and its identity archived in the community, so it no longer appears in member lists or mention suggestions."
+ : `Its ${instanceCount} agent instances are also deleted and their identities archived in the community, so they no longer appear in member lists or mention suggestions.`;
+ return `${persona.displayName} will be removed. ${cascade}`;
}
export function PersonaDeleteDialog({
@@ -76,7 +76,7 @@ export function PersonaDeleteDialog({
type="button"
variant="destructive"
>
- Delete
+ Delete agent
diff --git a/desktop/src/features/agents/ui/TeamDeleteDialog.tsx b/desktop/src/features/agents/ui/TeamDeleteDialog.tsx
index 383f92c4a5..03bc53980e 100644
--- a/desktop/src/features/agents/ui/TeamDeleteDialog.tsx
+++ b/desktop/src/features/agents/ui/TeamDeleteDialog.tsx
@@ -31,8 +31,8 @@ export function TeamDeleteDialog({
Delete team?
{team
- ? `Delete "${team.name}". Already-deployed agents are not affected, but this team template will no longer be available.`
- : "Delete this team."}
+ ? `"${team.name}" will no longer be available as a template. Already-deployed agents aren't affected.`
+ : "This team template will no longer be available."}
@@ -51,7 +51,7 @@ export function TeamDeleteDialog({
type="button"
variant="destructive"
>
- Delete
+ Delete team
diff --git a/desktop/src/features/agents/useOpenAgentActivity.ts b/desktop/src/features/agents/useOpenAgentActivity.ts
index e8cfc0e8ff..90e2dc3286 100644
--- a/desktop/src/features/agents/useOpenAgentActivity.ts
+++ b/desktop/src/features/agents/useOpenAgentActivity.ts
@@ -10,7 +10,7 @@ import { getAgentWorkingState } from "./agentWorkingSignal";
import { useRelayAgentsQuery } from "./hooks";
const INACCESSIBLE_ACTIVITY_MESSAGE =
- "This agent is active in a channel you haven't joined, so its activity can't be opened from here.";
+ "Can't open activity. It's in a channel you haven't joined.";
/**
* Can the viewer actually open this channel? Joined channels always;
diff --git a/desktop/src/features/channel-templates/useApplyTemplate.ts b/desktop/src/features/channel-templates/useApplyTemplate.ts
index 1f7d066fad..326cf15cca 100644
--- a/desktop/src/features/channel-templates/useApplyTemplate.ts
+++ b/desktop/src/features/channel-templates/useApplyTemplate.ts
@@ -16,6 +16,18 @@ import { useChannelTemplatesQuery } from "@/features/channel-templates/hooks";
import { setCanvas } from "@/shared/api/tauri";
import type { ChannelTemplate } from "@/shared/api/types";
+/**
+ * Format a list of failed agent names for a warning toast: up to three names
+ * are listed in full, then it falls back to "and N others" to keep the toast
+ * short. Mirrors the typing-indicator convention in TypingIndicatorRow.
+ */
+function formatFailedAgentNames(names: readonly string[]): string {
+ if (names.length === 1) return names[0];
+ if (names.length === 2) return `${names[0]} and ${names[1]}`;
+ if (names.length === 3) return `${names[0]}, ${names[1]}, and ${names[2]}`;
+ return `${names[0]}, ${names[1]}, and ${names.length - 2} others`;
+}
+
/**
* TemplateBackend omits `config` — supply an empty object for provider backends.
*/
@@ -135,10 +147,9 @@ export function useApplyTemplate() {
const result = await createChannelManagedAgents(channelId, inputs);
if (result.failures.length > 0) {
const { toast } = await import("sonner");
+ const failedNames = result.failures.map((failure) => failure.name);
toast.warning(
- result.failures.length === 1
- ? "1 agent from the template could not be created"
- : `${result.failures.length} agents from the template could not be created`,
+ `Couldn't add ${formatFailedAgentNames(failedNames)} from the template`,
);
}
await Promise.all([
diff --git a/desktop/src/features/channels/ui/AgentSessionThreadPanel.tsx b/desktop/src/features/channels/ui/AgentSessionThreadPanel.tsx
index a907f87245..64ac2cf6ae 100644
--- a/desktop/src/features/channels/ui/AgentSessionThreadPanel.tsx
+++ b/desktop/src/features/channels/ui/AgentSessionThreadPanel.tsx
@@ -246,14 +246,12 @@ export function AgentSessionThreadPanel({
try {
await cancelManagedAgentTurn(agent.pubkey, channel.id);
- toast.success(
- `Stop signal sent to ${agent.name}. It may take a moment to respond.`,
- );
+ toast.success(`Stopping ${agent.name}'s turn. This may take a moment.`);
} catch (error) {
toast.error(
error instanceof Error
? error.message
- : `Failed to stop ${agent.name}'s current turn.`,
+ : `Couldn't stop ${agent.name}'s current turn`,
);
}
}
diff --git a/desktop/src/features/channels/ui/MembersSidebarMemberCard.tsx b/desktop/src/features/channels/ui/MembersSidebarMemberCard.tsx
index 8234517432..2a5055406b 100644
--- a/desktop/src/features/channels/ui/MembersSidebarMemberCard.tsx
+++ b/desktop/src/features/channels/ui/MembersSidebarMemberCard.tsx
@@ -56,7 +56,11 @@ type MembersSidebarMemberCardProps = {
onManagedAgentAction: (agent: ManagedAgent) => void;
onOpenProfile?: (pubkey: string) => void;
onRemoveMember: (member: ChannelMember) => void;
- onTimeout: (member: ChannelMember, expiresAtSecs: number) => void;
+ onTimeout: (
+ member: ChannelMember,
+ expiresAtSecs: number,
+ durationLabel: string,
+ ) => void;
onUnban: (member: ChannelMember) => void;
onUntimeout: (member: ChannelMember) => void;
onViewActivity?: (pubkey: string) => void;
@@ -307,7 +311,11 @@ function MemberActionsMenu({
onEditRespondTo?: (agent: ManagedAgent) => void;
onManagedAgentAction: (agent: ManagedAgent) => void;
onRemoveMember: (member: ChannelMember) => void;
- onTimeout: (member: ChannelMember, expiresAtSecs: number) => void;
+ onTimeout: (
+ member: ChannelMember,
+ expiresAtSecs: number,
+ durationLabel: string,
+ ) => void;
onUnban: (member: ChannelMember) => void;
onUntimeout: (member: ChannelMember) => void;
onViewActivity?: (pubkey: string) => void;
@@ -439,6 +447,7 @@ function MemberActionsMenu({
onTimeout(
member,
Math.floor(Date.now() / 1000) + preset.seconds,
+ preset.label,
)
}
>
diff --git a/desktop/src/features/channels/ui/useMembersSidebarModeration.ts b/desktop/src/features/channels/ui/useMembersSidebarModeration.ts
index 04c4f1a70b..8ee2e6e408 100644
--- a/desktop/src/features/channels/ui/useMembersSidebarModeration.ts
+++ b/desktop/src/features/channels/ui/useMembersSidebarModeration.ts
@@ -55,7 +55,9 @@ export function useMembersSidebarModeration(open: boolean) {
toast.success(success);
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Moderation action failed",
+ error instanceof Error
+ ? error.message
+ : "Couldn't complete that action",
);
}
},
@@ -81,14 +83,14 @@ export function useMembersSidebarModeration(open: boolean) {
);
const onTimeout = React.useCallback(
- (member: ChannelMember, expiresAtSecs: number) =>
+ (member: ChannelMember, expiresAtSecs: number, durationLabel: string) =>
void runModerationAction(
() =>
timeoutMutation.mutateAsync({
pubkey: member.pubkey,
expiresAt: expiresAtSecs,
}),
- "Member timed out",
+ `Member timed out for ${durationLabel}`,
),
[timeoutMutation, runModerationAction],
);
diff --git a/desktop/src/features/chat/ui/ChatHeader.tsx b/desktop/src/features/chat/ui/ChatHeader.tsx
index 9ced506751..d9924a1017 100644
--- a/desktop/src/features/chat/ui/ChatHeader.tsx
+++ b/desktop/src/features/chat/ui/ChatHeader.tsx
@@ -108,7 +108,7 @@ export function ChatHeader({
await writeTextToClipboard(value);
toast.success("Channel name copied");
} catch {
- toast.error("Failed to copy channel name");
+ toast.error("Couldn't copy channel name");
}
}
diff --git a/desktop/src/features/communities/ui/CommunityIconSettingsCard.tsx b/desktop/src/features/communities/ui/CommunityIconSettingsCard.tsx
index 4f557fd8a3..ed757ec75d 100644
--- a/desktop/src/features/communities/ui/CommunityIconSettingsCard.tsx
+++ b/desktop/src/features/communities/ui/CommunityIconSettingsCard.tsx
@@ -42,7 +42,7 @@ export function CommunityIconSettingsCard() {
async function handleFile(file: File) {
if (!ICON_IMAGE_TYPES.includes(file.type)) {
- toast.error("Choose a PNG, JPG, GIF, or WebP image.");
+ toast.error("Choose a PNG, JPG, GIF, or WebP image");
return;
}
try {
@@ -53,7 +53,7 @@ export function CommunityIconSettingsCard() {
toast.error(
error instanceof Error
? error.message
- : "Failed to update the community icon.",
+ : "Couldn't update the community icon",
);
}
}
@@ -66,7 +66,7 @@ export function CommunityIconSettingsCard() {
toast.error(
error instanceof Error
? error.message
- : "Failed to remove the community icon.",
+ : "Couldn't remove the community icon",
);
}
}
diff --git a/desktop/src/features/communities/useNestNotifications.ts b/desktop/src/features/communities/useNestNotifications.ts
index d93bb89ad2..aa617ba3cc 100644
--- a/desktop/src/features/communities/useNestNotifications.ts
+++ b/desktop/src/features/communities/useNestNotifications.ts
@@ -23,7 +23,7 @@ const MIGRATION_TOAST_KEY = "buzz-legacy-nest-migrated-notified";
export function useNestNotifications(): void {
useEffect(() => {
const unlistenReposError = listen("repos-dir-error", (event) => {
- toast.error("Repos directory not applied", {
+ toast.error("Couldn't apply the repos directory", {
description: event.payload,
});
});
diff --git a/desktop/src/features/community-members/ui/CommunityMembersCard.tsx b/desktop/src/features/community-members/ui/CommunityMembersCard.tsx
index fdc75f3d18..57c3b340fe 100644
--- a/desktop/src/features/community-members/ui/CommunityMembersCard.tsx
+++ b/desktop/src/features/community-members/ui/CommunityMembersCard.tsx
@@ -205,7 +205,7 @@ export function CommunityMembersCard({
},
onError: (error) => {
toast.error(
- error instanceof Error ? error.message : "Failed to change role",
+ error instanceof Error ? error.message : "Couldn't change role",
);
},
},
diff --git a/desktop/src/features/community-members/ui/CommunityMembersSettingsCard.tsx b/desktop/src/features/community-members/ui/CommunityMembersSettingsCard.tsx
index 4572ad0017..632131e1cf 100644
--- a/desktop/src/features/community-members/ui/CommunityMembersSettingsCard.tsx
+++ b/desktop/src/features/community-members/ui/CommunityMembersSettingsCard.tsx
@@ -146,9 +146,7 @@ function RelayMemberRow({
toast.success(success);
} catch (error) {
toast.error(
- error instanceof Error
- ? error.message
- : "Community membership update failed",
+ error instanceof Error ? error.message : "Couldn't update membership",
);
}
}
@@ -196,7 +194,7 @@ function RelayMemberRow({
pubkey: member.pubkey,
role: "admin",
}),
- "Promoted relay admin",
+ `Promoted ${displayName} to admin`,
)
}
size="icon"
@@ -218,7 +216,7 @@ function RelayMemberRow({
pubkey: member.pubkey,
role: "member",
}),
- "Demoted to relay member",
+ `Demoted ${displayName} to member`,
)
}
size="icon"
@@ -237,7 +235,7 @@ function RelayMemberRow({
onClick={() =>
void mutateWithToast(
() => removeMutation.mutateAsync(member.pubkey),
- "Removed relay member",
+ `Removed ${displayName} from the community`,
)
}
size="icon"
@@ -339,14 +337,12 @@ export function CommunityMembersSettingsCard({
if (!canAdd) return;
try {
await addMutation.mutateAsync({ pubkey: normalizedInput, role });
- toast.success(
- role === "admin" ? "Added relay admin" : "Added relay member",
- );
+ toast.success(role === "admin" ? "Added as admin" : "Added as member");
setPubkeyInput("");
setRole("member");
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to add relay member",
+ error instanceof Error ? error.message : "Couldn't add member",
);
}
}
diff --git a/desktop/src/features/community-members/ui/ConfirmRemoveDialog.tsx b/desktop/src/features/community-members/ui/ConfirmRemoveDialog.tsx
index 64735a5d56..a8fdaf819e 100644
--- a/desktop/src/features/community-members/ui/ConfirmRemoveDialog.tsx
+++ b/desktop/src/features/community-members/ui/ConfirmRemoveDialog.tsx
@@ -43,7 +43,7 @@ export function ConfirmRemoveDialog({
Remove {label}?
- This will immediately revoke their access to the relay.
+ This will immediately revoke their access to the community.
{member ? (
Delete {label}?
- This will permanently delete this {label} and cannot be undone.
+ This will permanently delete this {label} and can't be undone.
diff --git a/desktop/src/features/huddle/components/HuddleAttachment.tsx b/desktop/src/features/huddle/components/HuddleAttachment.tsx
index 80e446f798..aa1aa1a979 100644
--- a/desktop/src/features/huddle/components/HuddleAttachment.tsx
+++ b/desktop/src/features/huddle/components/HuddleAttachment.tsx
@@ -222,7 +222,7 @@ export function HuddleAttachment({
void queryClient.invalidateQueries({ queryKey: ["channels"] });
} catch (error) {
const message =
- error instanceof Error ? error.message : "Failed to join huddle";
+ error instanceof Error ? error.message : "Couldn't join the huddle";
toast.error(message);
} finally {
setIsJoining(false);
diff --git a/desktop/src/features/identity-archive/hooks.ts b/desktop/src/features/identity-archive/hooks.ts
index 8149eff7b7..6b5bad0d09 100644
--- a/desktop/src/features/identity-archive/hooks.ts
+++ b/desktop/src/features/identity-archive/hooks.ts
@@ -153,10 +153,10 @@ export function useIdentityArchive(
archiveMutation.mutate(
{ targetPubkey },
{
- onSuccess: () => toast.success("Archived on this relay"),
+ onSuccess: () => toast.success("Archived in this community"),
onError: (error) =>
toast.error(
- `Archive failed: ${error instanceof Error ? error.message : String(error)}`,
+ `Couldn't archive: ${error instanceof Error ? error.message : String(error)}`,
),
},
);
@@ -167,10 +167,10 @@ export function useIdentityArchive(
unarchiveMutation.mutate(
{ targetPubkey },
{
- onSuccess: () => toast.success("Unarchived on this relay"),
+ onSuccess: () => toast.success("Unarchived in this community"),
onError: (error) =>
toast.error(
- `Unarchive failed: ${error instanceof Error ? error.message : String(error)}`,
+ `Couldn't unarchive: ${error instanceof Error ? error.message : String(error)}`,
),
},
);
diff --git a/desktop/src/features/local-archive/ui/LocalArchiveSettingsCard.tsx b/desktop/src/features/local-archive/ui/LocalArchiveSettingsCard.tsx
index fbf8c506eb..a9e7ed94a4 100644
--- a/desktop/src/features/local-archive/ui/LocalArchiveSettingsCard.tsx
+++ b/desktop/src/features/local-archive/ui/LocalArchiveSettingsCard.tsx
@@ -302,10 +302,10 @@ function AddSubscriptionForm({ channels, onSaved, onCancel }: AddFormProps) {
request.kinds,
);
onSaved();
- toast.success("Archive subscription created.");
+ toast.success("Archive subscription created");
} catch (err) {
toast.error(
- err instanceof Error ? err.message : "Failed to create subscription.",
+ err instanceof Error ? err.message : "Couldn't create the subscription",
);
} finally {
setIsAdding(false);
@@ -441,10 +441,12 @@ export function LocalArchiveSettingsCard() {
try {
await deleteSaveSubscription(scopeType, scopeValue);
await reload();
- toast.success("Archive subscription removed.");
+ toast.success("Archive subscription removed");
} catch (err) {
toast.error(
- err instanceof Error ? err.message : "Failed to remove subscription.",
+ err instanceof Error
+ ? err.message
+ : "Couldn't remove the subscription",
);
} finally {
setDeletingKey(null);
@@ -475,15 +477,15 @@ export function LocalArchiveSettingsCard() {
}
toast.success(
checked
- ? "Observer feed archive enabled."
- : "Observer feed archive disabled.",
+ ? "Observer feed archive enabled"
+ : "Observer feed archive disabled",
);
await reload();
} catch (err) {
toast.error(
err instanceof Error
? err.message
- : "Failed to update observer archive.",
+ : "Couldn't update the observer archive",
);
} finally {
setObserverToggling(false);
@@ -505,15 +507,15 @@ export function LocalArchiveSettingsCard() {
setExplicitAgentMetricArchiveChoice(pubkey, checked);
toast.success(
checked
- ? "Agent turn metric archive enabled."
- : "Agent turn metric archive disabled.",
+ ? "Agent turn metric archive enabled"
+ : "Agent turn metric archive disabled",
);
await reload();
} catch (err) {
toast.error(
err instanceof Error
? err.message
- : "Failed to update agent metric archive.",
+ : "Couldn't update the agent metric archive",
);
} finally {
setMetricToggling(false);
diff --git a/desktop/src/features/messages/hooks.ts b/desktop/src/features/messages/hooks.ts
index 3d34d07d1f..7d72306c04 100644
--- a/desktop/src/features/messages/hooks.ts
+++ b/desktop/src/features/messages/hooks.ts
@@ -670,7 +670,7 @@ export function useDeleteMessageMutation(channel: Channel | null) {
);
},
onError: (error) => {
- toast.error(`Failed to delete message: ${error.message}`);
+ toast.error(`Couldn't delete message: ${error.message}`);
},
});
}
diff --git a/desktop/src/features/messages/ui/DraftsPanel.tsx b/desktop/src/features/messages/ui/DraftsPanel.tsx
index 5a506a0a83..d019d03326 100644
--- a/desktop/src/features/messages/ui/DraftsPanel.tsx
+++ b/desktop/src/features/messages/ui/DraftsPanel.tsx
@@ -312,9 +312,9 @@ export function SendConfirmDialog({
>
- Send message
+ Send message?
- Are you sure you want to send this message to {destination}?
+ This message will be sent to {destination}.
diff --git a/desktop/src/features/messages/ui/MessageActionBar.tsx b/desktop/src/features/messages/ui/MessageActionBar.tsx
index ba45bc62fb..a57b0e8aa2 100644
--- a/desktop/src/features/messages/ui/MessageActionBar.tsx
+++ b/desktop/src/features/messages/ui/MessageActionBar.tsx
@@ -285,7 +285,7 @@ function MoreActionsMenu({
Delete message?
- This will permanently delete this message and cannot be undone.
+ This will permanently delete this message and can't be undone.
@@ -300,7 +300,7 @@ function MoreActionsMenu({
type="button"
variant="destructive"
>
- Delete
+ Delete message
diff --git a/desktop/src/features/messages/ui/SystemMessageRow.tsx b/desktop/src/features/messages/ui/SystemMessageRow.tsx
index 4410964dd9..b1d4377e3f 100644
--- a/desktop/src/features/messages/ui/SystemMessageRow.tsx
+++ b/desktop/src/features/messages/ui/SystemMessageRow.tsx
@@ -522,7 +522,7 @@ function describeSystemEvent(
title: membershipTitle,
action: (
<>
- was added by{" "}
+ added by{" "}
{resolveDisplayLabel(payload.actor, currentPubkey, profiles)}
@@ -566,7 +566,7 @@ function describeSystemEvent(
title: membershipTitle,
action: (
<>
- was added by{" "}
+ added by{" "}
{resolveDisplayLabel(payload.actor, currentPubkey, profiles)}
@@ -584,16 +584,28 @@ function describeSystemEvent(
title: actorName,
action: <>removed {targetName} from the channel>,
};
- case "topic_changed":
+ case "topic_changed": {
+ const topic = payload.topic?.trim();
return {
title: actorName,
- action: <>changed the topic to “{payload.topic}”>,
+ action: topic ? (
+ <>changed the topic to “{topic}”>
+ ) : (
+ "cleared the channel topic"
+ ),
};
- case "purpose_changed":
+ }
+ case "purpose_changed": {
+ const purpose = payload.purpose?.trim();
return {
title: actorName,
- action: <>changed the purpose to “{payload.purpose}”>,
+ action: purpose ? (
+ <>changed the purpose to “{purpose}”>
+ ) : (
+ "cleared the channel purpose"
+ ),
};
+ }
case "channel_created":
return {
title: actorName,
diff --git a/desktop/src/features/messages/ui/WaveMessageAttachment.tsx b/desktop/src/features/messages/ui/WaveMessageAttachment.tsx
index 0012d0b140..481edc8de8 100644
--- a/desktop/src/features/messages/ui/WaveMessageAttachment.tsx
+++ b/desktop/src/features/messages/ui/WaveMessageAttachment.tsx
@@ -46,7 +46,7 @@ export function WaveMessageAttachment({
await queryClient.invalidateQueries({ queryKey: channelsQueryKey });
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to start huddle.",
+ error instanceof Error ? error.message : "Couldn't start the huddle",
);
}
},
diff --git a/desktop/src/features/messages/ui/useMentionSendFlow.ts b/desktop/src/features/messages/ui/useMentionSendFlow.ts
index 6d4e007cd4..84e2797be2 100644
--- a/desktop/src/features/messages/ui/useMentionSendFlow.ts
+++ b/desktop/src/features/messages/ui/useMentionSendFlow.ts
@@ -142,7 +142,7 @@ function isProviderBackedAgent(agent: ManagedAgent) {
}
const DM_THREAD_AGENT_MENTION_ERROR =
- "Agents must already be in a DM to be mentioned in its threads. Start a new conversation that includes the agent.";
+ "You can only mention agents already in this DM. Start a new conversation to add them.";
const DM_THREAD_MEMBERS_LOADING_ERROR =
"Checking conversation members. Try again in a moment.";
@@ -490,8 +490,8 @@ export function useMentionSendFlow({
if (agentReadiness.errors.length > 0) {
const message =
agentReadiness.errors.length === 1
- ? `Could not start agent mention: ${agentReadiness.errors[0]}`
- : `Could not start agent mentions: ${agentReadiness.errors.join(
+ ? `Couldn't start agent mention: ${agentReadiness.errors[0]}`
+ : `Couldn't start agent mentions: ${agentReadiness.errors.join(
"; ",
)}`;
setNonMemberPromptError(message);
@@ -680,8 +680,8 @@ export function useMentionSendFlow({
if (personaMentionResult.errors.length > 0) {
const message =
personaMentionResult.errors.length === 1
- ? `Could not create agent mention: ${personaMentionResult.errors[0]}`
- : `Could not create agent mentions: ${personaMentionResult.errors.join(
+ ? `Couldn't create agent mention: ${personaMentionResult.errors[0]}`
+ : `Couldn't create agent mentions: ${personaMentionResult.errors.join(
"; ",
)}`;
setNonMemberPromptError(message);
diff --git a/desktop/src/features/moderation/ui/MessageModerationMenuItems.tsx b/desktop/src/features/moderation/ui/MessageModerationMenuItems.tsx
index e61f63b687..c4f89629c2 100644
--- a/desktop/src/features/moderation/ui/MessageModerationMenuItems.tsx
+++ b/desktop/src/features/moderation/ui/MessageModerationMenuItems.tsx
@@ -94,7 +94,9 @@ export function MessageModerationMenuItems({
toast.success(success);
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Moderation action failed",
+ error instanceof Error
+ ? error.message
+ : "Couldn't complete that action",
);
}
},
diff --git a/desktop/src/features/moderation/ui/ReportMessageDialog.tsx b/desktop/src/features/moderation/ui/ReportMessageDialog.tsx
index 1cbc71c90d..ceb8dfebd6 100644
--- a/desktop/src/features/moderation/ui/ReportMessageDialog.tsx
+++ b/desktop/src/features/moderation/ui/ReportMessageDialog.tsx
@@ -67,7 +67,7 @@ export function ReportMessageDialog({
toast.success("Report submitted to community moderators");
onOpenChange(false);
},
- onError: () => toast.error("Failed to submit report"),
+ onError: () => toast.error("Couldn't submit report"),
},
);
};
diff --git a/desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx b/desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx
index 2d040ff348..fe24fccc69 100644
--- a/desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx
+++ b/desktop/src/features/onboarding/ui/MachineOnboardingFlow.tsx
@@ -151,7 +151,7 @@ export function MachineOnboardingFlow({
const replaceLostIdentity = React.useCallback(async () => {
const confirmed = window.confirm(
- "This will create a new identity and abandon your previous key. This cannot be undone. Continue?",
+ "This will create a new identity and abandon your previous key. This can't be undone. Continue?",
);
if (!confirmed) return;
diff --git a/desktop/src/features/onboarding/ui/OnboardingFlow.tsx b/desktop/src/features/onboarding/ui/OnboardingFlow.tsx
index 01a226e3de..5c5be70063 100644
--- a/desktop/src/features/onboarding/ui/OnboardingFlow.tsx
+++ b/desktop/src/features/onboarding/ui/OnboardingFlow.tsx
@@ -407,7 +407,7 @@ export function OnboardingFlow({
// RelaunchRequiredScreen. No navigation needed here.
const handleLostModeBack = React.useCallback(async () => {
const confirmed = window.confirm(
- "This will create a new identity and abandon your previous key. This cannot be undone. Continue?",
+ "This will create a new identity and abandon your previous key. This can't be undone. Continue?",
);
if (!confirmed) {
return;
diff --git a/desktop/src/features/onboarding/ui/ProfileStep.tsx b/desktop/src/features/onboarding/ui/ProfileStep.tsx
index 69da9b8f7c..6158c83fb2 100644
--- a/desktop/src/features/onboarding/ui/ProfileStep.tsx
+++ b/desktop/src/features/onboarding/ui/ProfileStep.tsx
@@ -123,7 +123,7 @@ function OnboardingRelayConnectionErrorCard({
.catch((error) => {
hadActiveReconnectRef.current = false;
const detail = error instanceof Error ? error.message : String(error);
- toast.error(`Could not reconnect to the relay. ${detail}`);
+ toast.error(`Couldn't reconnect to the relay. ${detail}`);
})
.finally(() => {
reconnectActionPendingRef.current = false;
diff --git a/desktop/src/features/profile/ui/ArchiveConfirmDialog.tsx b/desktop/src/features/profile/ui/ArchiveConfirmDialog.tsx
index 2f750543db..e6afaa9e02 100644
--- a/desktop/src/features/profile/ui/ArchiveConfirmDialog.tsx
+++ b/desktop/src/features/profile/ui/ArchiveConfirmDialog.tsx
@@ -39,7 +39,7 @@ export function ArchiveConfirmDialog({
{title}
- Archiving hides {subject} from the space.
+ Archiving hides {subject} from the community.
{/* The list + closing paragraph sit outside AlertDialogDescription on
@@ -51,8 +51,8 @@ export function ArchiveConfirmDialog({
This only affects{" "}
- this space —
- not their account anywhere else
+ this community{" "}
+ — not their account anywhere else
You can unarchive them at any time to restore them
diff --git a/desktop/src/features/profile/ui/UserProfileAgentActions.tsx b/desktop/src/features/profile/ui/UserProfileAgentActions.tsx
index 81db3405b2..3e2b44918b 100644
--- a/desktop/src/features/profile/ui/UserProfileAgentActions.tsx
+++ b/desktop/src/features/profile/ui/UserProfileAgentActions.tsx
@@ -310,7 +310,7 @@ function AgentDeleteConfirmDialog({
- Delete this agent?
+ Delete agent?
Deleting this agent stops and removes the agent from this community.
diff --git a/desktop/src/features/profile/ui/UserProfilePanel.tsx b/desktop/src/features/profile/ui/UserProfilePanel.tsx
index 09e8d51487..cbba282db9 100644
--- a/desktop/src/features/profile/ui/UserProfilePanel.tsx
+++ b/desktop/src/features/profile/ui/UserProfilePanel.tsx
@@ -462,7 +462,7 @@ export function UserProfilePanel({
relayAgents: relayAgentsQuery.data ?? [],
stopManagedAgent: stopAgentMutation.mutateAsync,
});
- toast.success(result.noticeMessage ?? `Stopped ${managedAgent.name}.`);
+ toast.success(result.noticeMessage ?? `Stopped ${managedAgent.name}`);
return;
}
@@ -472,12 +472,14 @@ export function UserProfilePanel({
});
toast.success(
managedAgent.backend.type === "provider"
- ? `Deploying ${managedAgent.name}.`
- : `Started ${managedAgent.name}.`,
+ ? `Deploying ${managedAgent.name}`
+ : `Started ${managedAgent.name}`,
);
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Agent action failed.",
+ error instanceof Error
+ ? error.message
+ : "Couldn't complete that action",
);
}
}, [
@@ -496,14 +498,14 @@ export function UserProfilePanel({
if (created.spawnError) {
toast.error(created.spawnError);
} else {
- toast.success(`Started ${created.agent.name}.`);
+ toast.success(`Started ${created.agent.name}`);
}
if (created.profileSyncError) {
toast.warning(created.profileSyncError);
}
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to start agent.",
+ error instanceof Error ? error.message : "Couldn't start the agent",
);
}
}, [createManagedAgentForPersona, resolvedPersona]);
@@ -518,14 +520,14 @@ export function UserProfilePanel({
});
toast.success(
updated.startOnAppLaunch
- ? `Will start ${updated.name} automatically.`
- : `${updated.name} will stay manual-start only.`,
+ ? `Will start ${updated.name} automatically`
+ : `${updated.name} will stay manual-start only`,
);
} catch (error) {
toast.error(
error instanceof Error
? error.message
- : "Failed to update startup preference.",
+ : "Couldn't update the startup preference",
);
}
}, [managedAgent, startOnLaunchMutation.mutateAsync]);
@@ -537,11 +539,11 @@ export function UserProfilePanel({
const result = await deleteManagedAgentRecord(managedAgent);
if (result.cancelled) return;
- toast.success(`Deleted ${managedAgent.name}.`);
+ toast.success(`Deleted ${managedAgent.name}`);
onClose();
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to delete agent.",
+ error instanceof Error ? error.message : "Couldn't delete agent",
);
}
}, [deleteManagedAgentRecord, managedAgent, onClose]);
@@ -604,18 +606,18 @@ export function UserProfilePanel({
id: resolvedPersona.id,
active: false,
});
- toast.success(`Removed ${resolvedPersona.displayName} from My Agents.`);
+ toast.success(`Removed ${resolvedPersona.displayName} from My Agents`);
onClose();
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to delete agent.",
+ error instanceof Error ? error.message : "Couldn't delete agent",
);
}
return;
}
if (resolvedPersona.sourceTeam) {
- toast.error("This agent is managed by a team.");
+ toast.error("This agent is managed by a team");
return;
}
@@ -630,19 +632,19 @@ export function UserProfilePanel({
const handleConfirmDeletePersona = React.useCallback(
async (personaToConfirm: AgentPersona) => {
if (personaToConfirm.sourceTeam) {
- toast.error("This agent is managed by a team.");
+ toast.error("This agent is managed by a team");
setPersonaToDelete(null);
return;
}
try {
await deletePersonaMutation.mutateAsync(personaToConfirm.id);
- toast.success(`Deleted ${personaToConfirm.displayName}.`);
+ toast.success(`Deleted ${personaToConfirm.displayName}`);
setPersonaToDelete(null);
onClose();
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to delete agent.",
+ error instanceof Error ? error.message : "Couldn't delete agent",
);
}
},
@@ -664,11 +666,11 @@ export function UserProfilePanel({
const handleAddedToChannel = React.useCallback(
(channel: Channel, result: AttachManagedAgentToChannelResult) => {
if (result.started) {
- toast.success(`Added ${result.agent.name} to ${channel.name}.`);
+ toast.success(`Added ${result.agent.name} to ${channel.name}`);
} else if (result.membershipAdded) {
- toast.success(`Added ${result.agent.name} to ${channel.name}.`);
+ toast.success(`Added ${result.agent.name} to ${channel.name}`);
} else {
- toast.success(`${result.agent.name} is already in ${channel.name}.`);
+ toast.success(`${result.agent.name} is already in ${channel.name}`);
}
void managedAgentsQuery.refetch();
void relayAgentsQuery.refetch();
diff --git a/desktop/src/features/profile/ui/UserProfilePanelPersonaSubmit.ts b/desktop/src/features/profile/ui/UserProfilePanelPersonaSubmit.ts
index eff9a1af10..2fc0d41c04 100644
--- a/desktop/src/features/profile/ui/UserProfilePanelPersonaSubmit.ts
+++ b/desktop/src/features/profile/ui/UserProfilePanelPersonaSubmit.ts
@@ -100,7 +100,7 @@ export async function submitProfilePersonaDialog({
`${result.agent.name} was updated, but profile sync failed: ${result.profileSyncError}`,
);
}
- toast.success(`Updated ${input.displayName}.`);
+ toast.success(`Updated ${input.displayName}`);
} else {
const persona = await createPersona(input);
try {
@@ -110,7 +110,7 @@ export async function submitProfilePersonaDialog({
`${persona.displayName} was created, but it did not start: ${created.spawnError}`,
);
} else {
- toast.success(`Created and started ${created.agent.name}.`);
+ toast.success(`Created and started ${created.agent.name}`);
}
if (created.profileSyncError) {
toast.warning(
@@ -120,16 +120,14 @@ export async function submitProfilePersonaDialog({
} catch (error) {
toast.error(
error instanceof Error
- ? `${persona.displayName} was created, but the agent instance could not be created: ${error.message}`
- : `${persona.displayName} was created, but the agent instance could not be created.`,
+ ? `${persona.displayName} was created, but the agent instance couldn't be created: ${error.message}`
+ : `${persona.displayName} was created, but the agent instance couldn't be created.`,
);
}
}
onDone();
} catch (error) {
- toast.error(
- error instanceof Error ? error.message : "Failed to save agent.",
- );
+ toast.error(error instanceof Error ? error.message : "Couldn't save agent");
}
}
diff --git a/desktop/src/features/profile/ui/UserProfilePanelSections.tsx b/desktop/src/features/profile/ui/UserProfilePanelSections.tsx
index 2a46dcc7a5..2fbd894e97 100644
--- a/desktop/src/features/profile/ui/UserProfilePanelSections.tsx
+++ b/desktop/src/features/profile/ui/UserProfilePanelSections.tsx
@@ -654,7 +654,7 @@ function ProfilePrimaryActions({
followToggleMutation.mutate(pubkey, {
onError: (error) =>
toast.error(
- `${isFollowing ? "Unfollow" : "Follow"} failed: ${error.message}`,
+ `Couldn't ${isFollowing ? "unfollow" : "follow"}: ${error.message}`,
),
});
};
diff --git a/desktop/src/features/profile/ui/UserProfilePopover.tsx b/desktop/src/features/profile/ui/UserProfilePopover.tsx
index 9161bac302..cb7903dbab 100644
--- a/desktop/src/features/profile/ui/UserProfilePopover.tsx
+++ b/desktop/src/features/profile/ui/UserProfilePopover.tsx
@@ -334,9 +334,7 @@ export function UserProfilePopover({
}
} catch (error) {
toast.error(
- error instanceof Error
- ? error.message
- : "Failed to open direct message.",
+ error instanceof Error ? error.message : "Couldn't open direct message",
);
} finally {
if (isMountedRef.current) {
@@ -375,7 +373,7 @@ export function UserProfilePopover({
}
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to start huddle.",
+ error instanceof Error ? error.message : "Couldn't start huddle",
);
} finally {
if (isMountedRef.current) {
@@ -472,7 +470,7 @@ export function UserProfilePopover({
}
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to send wave.",
+ error instanceof Error ? error.message : "Couldn't send wave",
);
} finally {
if (isMountedRef.current) {
diff --git a/desktop/src/features/profile/ui/UserProfileSnapshotExportDialog.tsx b/desktop/src/features/profile/ui/UserProfileSnapshotExportDialog.tsx
index 003c12c812..9de7bff7d1 100644
--- a/desktop/src/features/profile/ui/UserProfileSnapshotExportDialog.tsx
+++ b/desktop/src/features/profile/ui/UserProfileSnapshotExportDialog.tsx
@@ -33,7 +33,7 @@ export function UserProfileSnapshotExportDialog({
{
onSuccess: (saved) => {
if (saved) {
- toast.success(`Exported ${persona.displayName}.`);
+ toast.success(`Exported ${persona.displayName}`);
onOpenChange(false);
}
},
@@ -41,7 +41,7 @@ export function UserProfileSnapshotExportDialog({
toast.error(
error instanceof Error
? error.message
- : "Failed to export agent snapshot.",
+ : "Couldn't export agent snapshot",
);
},
},
diff --git a/desktop/src/features/profile/ui/useProfileDmAction.ts b/desktop/src/features/profile/ui/useProfileDmAction.ts
index 0d5811333a..0f3e4afaa9 100644
--- a/desktop/src/features/profile/ui/useProfileDmAction.ts
+++ b/desktop/src/features/profile/ui/useProfileDmAction.ts
@@ -32,9 +32,7 @@ export function useProfileDmAction({
} catch (error) {
if (!isMountedRef.current) return;
toast.error(
- error instanceof Error
- ? error.message
- : "Failed to open direct message.",
+ error instanceof Error ? error.message : "Couldn't open direct message",
);
setIsOpeningDm(false);
return;
diff --git a/desktop/src/features/projects/ui/CreateProjectIssueDialog.tsx b/desktop/src/features/projects/ui/CreateProjectIssueDialog.tsx
index af28693bb4..d3c9537c03 100644
--- a/desktop/src/features/projects/ui/CreateProjectIssueDialog.tsx
+++ b/desktop/src/features/projects/ui/CreateProjectIssueDialog.tsx
@@ -39,7 +39,7 @@ export function CreateProjectIssueDialog({
async function handleCreate(input: CreateProjectWorkItemDialogInput) {
if (!project) throw new Error("Choose a repository.");
const issueId = await createMutation.mutateAsync(input);
- toast.success("Issue created.");
+ toast.success("Issue created");
await onCreated(project, issueId);
}
diff --git a/desktop/src/features/projects/ui/CreatePullRequestDialog.tsx b/desktop/src/features/projects/ui/CreatePullRequestDialog.tsx
index d64d132aed..11af95f1e5 100644
--- a/desktop/src/features/projects/ui/CreatePullRequestDialog.tsx
+++ b/desktop/src/features/projects/ui/CreatePullRequestDialog.tsx
@@ -138,7 +138,7 @@ export function CreatePullRequestDialog({
mergeBase: sourceSyncQuery.data?.mergeBase ?? null,
reviewers: [],
});
- toast.success("Pull request created.");
+ toast.success("Pull request created");
await onCreated(project, pullRequestId);
}
diff --git a/desktop/src/features/projects/ui/MergePullRequestButton.tsx b/desktop/src/features/projects/ui/MergePullRequestButton.tsx
index 133c41d043..ba0588bb76 100644
--- a/desktop/src/features/projects/ui/MergePullRequestButton.tsx
+++ b/desktop/src/features/projects/ui/MergePullRequestButton.tsx
@@ -105,9 +105,7 @@ export function MergePullRequestButton({
setConfirmOpen(false);
}
toast.error(
- error instanceof Error
- ? error.message
- : "Failed to merge pull request.",
+ error instanceof Error ? error.message : "Failed to merge pull request",
);
}
}, [mergeMutation, pullRequest]);
@@ -138,12 +136,12 @@ export function MergePullRequestButton({
recoveryRef: result.recoveryRef,
targetRef: result.targetRef,
});
- toast.success("Recovery commit fetched and terminal opened.");
+ toast.success("Recovery commit fetched and terminal opened");
} catch (error) {
toast.error(
error instanceof Error
? error.message
- : "Failed to prepare merge recovery.",
+ : "Failed to prepare merge recovery",
);
} finally {
setIsPreparingRecovery(false);
@@ -164,12 +162,12 @@ export function MergePullRequestButton({
statusEvent: unpublishedStatusEvent,
});
setUnpublishedStatusState(null);
- toast.success("Published merged pull request status.");
+ toast.success("Published merged pull request status");
} catch (error) {
toast.error(
error instanceof Error
? error.message
- : "Failed to publish merged pull request status.",
+ : "Failed to publish merged pull request status",
);
}
}, [publishMergedMutation, unpublishedStatusEvent]);
diff --git a/desktop/src/features/projects/ui/ProjectCards.tsx b/desktop/src/features/projects/ui/ProjectCards.tsx
index 52308f7a05..5a38355287 100644
--- a/desktop/src/features/projects/ui/ProjectCards.tsx
+++ b/desktop/src/features/projects/ui/ProjectCards.tsx
@@ -363,7 +363,7 @@ function ProjectActionsMenu({
Delete project?
Delete {project.name} from Projects for everyone. This can only be
- done for projects you own and cannot be undone.
+ done for projects you own and can't be undone.
diff --git a/desktop/src/features/projects/ui/ProjectDetailScreen.tsx b/desktop/src/features/projects/ui/ProjectDetailScreen.tsx
index f67d535513..5dc75dcf1a 100644
--- a/desktop/src/features/projects/ui/ProjectDetailScreen.tsx
+++ b/desktop/src/features/projects/ui/ProjectDetailScreen.tsx
@@ -278,13 +278,13 @@ export function ProjectDetailScreen(props: ProjectDetailScreenProps) {
]);
const error = results.find((result) => result.error)?.error;
if (error) {
- toast.error("Could not fetch repository.", {
+ toast.error("Couldn't fetch repository", {
description:
error instanceof Error ? error.message : "The Git fetch failed.",
});
return;
}
- toast.success("Remote state refreshed.");
+ toast.success("Remote state refreshed");
}, [repoSnapshotQuery, repoStateQuery, repoSyncStatusQuery]);
// Compact branch + remote/local controls shared by the readme and Files
// tab headers.
@@ -515,7 +515,7 @@ export function ProjectDetailScreen(props: ProjectDetailScreenProps) {
const handleCreateIssue = React.useCallback(
async ({ body, title }: CreateIssueDialogInput) => {
const issueId = await createIssueMutation.mutateAsync({ body, title });
- toast.success("Issue created.");
+ toast.success("Issue created");
await issuesQuery.refetch();
setSelectedIssueId(issueId);
},
@@ -530,7 +530,7 @@ export function ProjectDetailScreen(props: ProjectDetailScreenProps) {
mergeBase: repoSyncStatusQuery.data?.mergeBase ?? null,
});
toast.success(
- updated ? "Pull request updated." : "Pull request is already current.",
+ updated ? "Pull request updated" : "Pull request is already current",
);
await pullRequestsQuery.refetch();
} catch (error) {
diff --git a/desktop/src/features/projects/ui/ProjectIssuesPanel.tsx b/desktop/src/features/projects/ui/ProjectIssuesPanel.tsx
index 861645a248..d3558f7291 100644
--- a/desktop/src/features/projects/ui/ProjectIssuesPanel.tsx
+++ b/desktop/src/features/projects/ui/ProjectIssuesPanel.tsx
@@ -193,10 +193,10 @@ function IssueDetail({
mediaTags,
mentionPubkeys,
});
- toast.success("Comment posted.");
+ toast.success("Comment posted");
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to post comment.",
+ error instanceof Error ? error.message : "Failed to post comment",
);
throw error;
}
diff --git a/desktop/src/features/projects/ui/ProjectPullRequestFilesChangedPanel.tsx b/desktop/src/features/projects/ui/ProjectPullRequestFilesChangedPanel.tsx
index ba94db68e8..a70947a305 100644
--- a/desktop/src/features/projects/ui/ProjectPullRequestFilesChangedPanel.tsx
+++ b/desktop/src/features/projects/ui/ProjectPullRequestFilesChangedPanel.tsx
@@ -641,12 +641,12 @@ export function ProjectPullRequestFilesChangedPanel({
pullRequest,
});
setActiveAnchor(null);
- toast.success("Line comment posted.");
+ toast.success("Line comment posted");
} catch (error) {
toast.error(
error instanceof Error
? error.message
- : "Failed to post line comment.",
+ : "Failed to post line comment",
);
throw error;
}
diff --git a/desktop/src/features/projects/ui/ProjectPullRequestsPanel.tsx b/desktop/src/features/projects/ui/ProjectPullRequestsPanel.tsx
index 4e2dbb2a53..a3a472db7e 100644
--- a/desktop/src/features/projects/ui/ProjectPullRequestsPanel.tsx
+++ b/desktop/src/features/projects/ui/ProjectPullRequestsPanel.tsx
@@ -479,10 +479,10 @@ function PullRequestDetail({
mentionPubkeys,
pullRequest,
});
- toast.success("Comment posted.");
+ toast.success("Comment posted");
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to post comment.",
+ error instanceof Error ? error.message : "Failed to post comment",
);
throw error;
}
diff --git a/desktop/src/features/projects/ui/ProjectsAgentPromptPage.tsx b/desktop/src/features/projects/ui/ProjectsAgentPromptPage.tsx
index 29705425f6..be4502868a 100644
--- a/desktop/src/features/projects/ui/ProjectsAgentPromptPage.tsx
+++ b/desktop/src/features/projects/ui/ProjectsAgentPromptPage.tsx
@@ -397,7 +397,7 @@ export function ProjectsAgentPromptPage({
richText.clearContent();
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to reach the agent",
+ error instanceof Error ? error.message : "Couldn't reach agent",
);
} finally {
setIsSending(false);
diff --git a/desktop/src/features/projects/ui/ProjectsView.tsx b/desktop/src/features/projects/ui/ProjectsView.tsx
index 2f22bfe0c1..ff4afba191 100644
--- a/desktop/src/features/projects/ui/ProjectsView.tsx
+++ b/desktop/src/features/projects/ui/ProjectsView.tsx
@@ -603,7 +603,7 @@ export function ProjectsView() {
isCreating={createProjectMutation.isPending}
onCreate={async (input) => {
const project = await createProjectMutation.mutateAsync(input);
- toast.success(`Project "${project.name}" created.`);
+ toast.success(`Project "${project.name}" created`);
// Land on the list that actually shows the new project — the
// Overview only surfaces the top few most-active repositories.
handleRepositoryScopeChange("all");
diff --git a/desktop/src/features/projects/ui/PullRequestReviewCard.tsx b/desktop/src/features/projects/ui/PullRequestReviewCard.tsx
index bf2f074a8b..51aca9978f 100644
--- a/desktop/src/features/projects/ui/PullRequestReviewCard.tsx
+++ b/desktop/src/features/projects/ui/PullRequestReviewCard.tsx
@@ -86,12 +86,12 @@ export function PullRequestReviewCard({
await updatePullRequestStatus({ pullRequest, status });
toast.success(
status === "draft"
- ? "Converted to draft."
- : "Marked as ready for review.",
+ ? "Converted to draft"
+ : "Marked as ready for review",
);
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to update status.",
+ error instanceof Error ? error.message : "Failed to update status",
);
}
},
@@ -135,16 +135,16 @@ export function PullRequestReviewCard({
const handleApprove = React.useCallback(async () => {
await runReviewDecision(
approvePullRequest,
- "Pull request approved.",
- "Failed to approve.",
+ "Pull request approved",
+ "Failed to approve",
);
}, [approvePullRequest, runReviewDecision]);
const handleRequestChanges = React.useCallback(async () => {
await runReviewDecision(
requestPullRequestChanges,
- "Changes requested.",
- "Failed to request changes.",
+ "Changes requested",
+ "Failed to request changes",
);
}, [requestPullRequestChanges, runReviewDecision]);
diff --git a/desktop/src/features/projects/ui/PullRequestReviewersRow.tsx b/desktop/src/features/projects/ui/PullRequestReviewersRow.tsx
index 63c5be94b1..9d180dad67 100644
--- a/desktop/src/features/projects/ui/PullRequestReviewersRow.tsx
+++ b/desktop/src/features/projects/ui/PullRequestReviewersRow.tsx
@@ -106,10 +106,10 @@ export function PullRequestReviewersRow({
});
setPickerOpen(false);
setReviewerQuery("");
- toast.success("Review requested.");
+ toast.success("Review requested");
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to request review.",
+ error instanceof Error ? error.message : "Failed to request review",
);
} finally {
requestInFlightRef.current = false;
diff --git a/desktop/src/features/projects/ui/useOpenProjectTerminal.ts b/desktop/src/features/projects/ui/useOpenProjectTerminal.ts
index 64d2415536..6defabed6a 100644
--- a/desktop/src/features/projects/ui/useOpenProjectTerminal.ts
+++ b/desktop/src/features/projects/ui/useOpenProjectTerminal.ts
@@ -43,7 +43,7 @@ export function useOpenProjectTerminal(reposDir?: string | null) {
}
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to open terminal",
+ error instanceof Error ? error.message : "Couldn't open the terminal",
{ id: toastId },
);
}
diff --git a/desktop/src/features/pulse/lib/useNoteActions.ts b/desktop/src/features/pulse/lib/useNoteActions.ts
index 8178cdc53a..a88bf67234 100644
--- a/desktop/src/features/pulse/lib/useNoteActions.ts
+++ b/desktop/src/features/pulse/lib/useNoteActions.ts
@@ -98,7 +98,7 @@ export function usePulseNoteActions({
queryClient.setQueryData(reactionQueryKey, previousReactions);
toast.error(
- error instanceof Error ? error.message : "Failed to update reaction",
+ error instanceof Error ? error.message : "Couldn't update reaction",
);
} finally {
setPendingUpvoteNoteIds((current) =>
@@ -135,7 +135,7 @@ export function usePulseNoteActions({
});
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to post reply",
+ error instanceof Error ? error.message : "Couldn't post reply",
);
throw error;
}
@@ -148,7 +148,7 @@ export function usePulseNoteActions({
await writeTextToClipboard(buildNoteShareUri(note));
toast.success("Copied note link");
} catch {
- toast.error("Failed to copy note link");
+ toast.error("Couldn't copy note link");
}
}, []);
@@ -164,7 +164,7 @@ export function usePulseNoteActions({
});
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to open DM",
+ error instanceof Error ? error.message : "Couldn't open DM",
);
}
},
diff --git a/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx b/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx
index 2833eee45f..bcdc936eba 100644
--- a/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx
+++ b/desktop/src/features/reminders/ui/RemindMeLaterDialog.tsx
@@ -48,7 +48,7 @@ export function RemindMeLaterDialog({
onOpenChange(false);
setNote("");
},
- onError: () => toast.error("Failed to create reminder"),
+ onError: () => toast.error("Couldn't create reminder"),
},
);
};
diff --git a/desktop/src/features/reminders/ui/RemindersPanel.tsx b/desktop/src/features/reminders/ui/RemindersPanel.tsx
index 651768a251..630971cb1f 100644
--- a/desktop/src/features/reminders/ui/RemindersPanel.tsx
+++ b/desktop/src/features/reminders/ui/RemindersPanel.tsx
@@ -72,7 +72,7 @@ function ReminderRow({
const handleComplete = () => {
complete.mutate(reminder, {
onSuccess: () => toast.success("Reminder completed"),
- onError: () => toast.error("Failed to complete reminder"),
+ onError: () => toast.error("Couldn't complete reminder"),
});
};
@@ -81,7 +81,7 @@ function ReminderRow({
{ reminder, notBefore },
{
onSuccess: () => toast.success("Reminder snoozed"),
- onError: () => toast.error("Failed to snooze reminder"),
+ onError: () => toast.error("Couldn't snooze reminder"),
},
);
};
@@ -89,7 +89,7 @@ function ReminderRow({
const handleCancel = () => {
cancel.mutate(reminder, {
onSuccess: () => toast.success("Reminder cancelled"),
- onError: () => toast.error("Failed to cancel reminder"),
+ onError: () => toast.error("Couldn't cancel reminder"),
});
};
diff --git a/desktop/src/features/settings/ui/ChannelTemplatesSettingsCard.tsx b/desktop/src/features/settings/ui/ChannelTemplatesSettingsCard.tsx
index 6c149aaab0..264f55e302 100644
--- a/desktop/src/features/settings/ui/ChannelTemplatesSettingsCard.tsx
+++ b/desktop/src/features/settings/ui/ChannelTemplatesSettingsCard.tsx
@@ -77,7 +77,7 @@ export function ChannelTemplatesSettingsCard() {
},
onError: (error) => {
toast.error(
- error instanceof Error ? error.message : "Failed to duplicate",
+ error instanceof Error ? error.message : "Couldn't duplicate",
);
},
});
@@ -91,9 +91,7 @@ export function ChannelTemplatesSettingsCard() {
setDeleteTarget(null);
},
onError: (error) => {
- toast.error(
- error instanceof Error ? error.message : "Failed to delete",
- );
+ toast.error(error instanceof Error ? error.message : "Couldn't delete");
},
});
}
@@ -167,10 +165,10 @@ export function ChannelTemplatesSettingsCard() {
>
- Delete template
+ Delete template?
- Are you sure you want to delete "{deleteTarget?.name}"?
- This action cannot be undone.
+ Delete "{deleteTarget?.name}". This can't be
+ undone.
@@ -179,7 +177,7 @@ export function ChannelTemplatesSettingsCard() {
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
onClick={handleDelete}
>
- Delete
+ Delete template
@@ -368,7 +366,7 @@ function TemplateFormDialog({
},
onError: (error) => {
toast.error(
- error instanceof Error ? error.message : "Failed to update",
+ error instanceof Error ? error.message : "Couldn't update",
);
},
});
@@ -387,7 +385,7 @@ function TemplateFormDialog({
},
onError: (error) => {
toast.error(
- error instanceof Error ? error.message : "Failed to create",
+ error instanceof Error ? error.message : "Couldn't create",
);
},
});
diff --git a/desktop/src/features/settings/ui/ModerationQueueCard.tsx b/desktop/src/features/settings/ui/ModerationQueueCard.tsx
index ca9adf980d..6e3cdd7668 100644
--- a/desktop/src/features/settings/ui/ModerationQueueCard.tsx
+++ b/desktop/src/features/settings/ui/ModerationQueueCard.tsx
@@ -414,7 +414,7 @@ function QueueTab() {
);
} catch (error) {
toast.error(
- error instanceof Error ? error.message : "Failed to resolve the report",
+ error instanceof Error ? error.message : "Couldn't resolve the report",
);
}
}
diff --git a/desktop/src/features/settings/ui/ProfileSettingsCard.tsx b/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
index d09a4fed64..18e58f4ec6 100644
--- a/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
+++ b/desktop/src/features/settings/ui/ProfileSettingsCard.tsx
@@ -965,7 +965,7 @@ export function ProfileSettingsCard({
Sign out
Removes your identity key and all local app data from this device.
- Back up your private key (nsec) first — this cannot be undone.
+ Back up your private key (nsec) first — this can't be undone.
) : null}
- {isSignOutPending ? "Signing out…" : "Sign Out"}
+ {isSignOutPending ? "Signing out…" : "Sign out"}
@@ -1013,12 +1013,12 @@ export function ProfileSettingsCard({
setIsSignOutPending(false);
setIsSignOutOpen(false);
toast.error(
- err instanceof Error ? err.message : "Sign out failed.",
+ err instanceof Error ? err.message : "Couldn't sign out",
);
});
}}
>
- {isSignOutPending ? "Signing out…" : "Sign Out"}
+ {isSignOutPending ? "Signing out…" : "Sign out"}
diff --git a/desktop/src/features/sidebar/ui/ChannelSectionDialogs.tsx b/desktop/src/features/sidebar/ui/ChannelSectionDialogs.tsx
index 6b054fa600..78c2578c76 100644
--- a/desktop/src/features/sidebar/ui/ChannelSectionDialogs.tsx
+++ b/desktop/src/features/sidebar/ui/ChannelSectionDialogs.tsx
@@ -249,14 +249,14 @@ export function DeleteSectionAlertDialog({
channelCount === 1 ? "1 channel" : `${channelCount} channels`;
const description =
channelCount === 0
- ? `Delete section "${sectionName}"? It has no channels.`
- : `Delete section "${sectionName}"? Its ${channelLabel} will move back to the default Channels group.`;
+ ? `"${sectionName}" has no channels.`
+ : `Its ${channelLabel} will move back to the default Channels group.`;
return (
- Delete section
+ Delete section?{description}
@@ -265,7 +265,7 @@ export function DeleteSectionAlertDialog({
className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
onClick={onConfirm}
>
- Delete
+ Delete section
@@ -294,9 +294,9 @@ export function LeaveChannelAlertDialog({
- Leave channel
+ Leave channel?
- {`Leave "${channelName}"? You'll stop receiving its messages and can rejoin later.`}
+ {`You'll stop receiving messages from "${channelName}" and can rejoin later.`}
diff --git a/desktop/src/features/workflows/ui/WorkflowDeleteDialog.tsx b/desktop/src/features/workflows/ui/WorkflowDeleteDialog.tsx
index db07470f2c..423071977b 100644
--- a/desktop/src/features/workflows/ui/WorkflowDeleteDialog.tsx
+++ b/desktop/src/features/workflows/ui/WorkflowDeleteDialog.tsx
@@ -31,8 +31,8 @@ export function WorkflowDeleteDialog({
Delete workflow?
{workflow
- ? `Delete "${workflow.name}". This will stop all future triggers and remove the workflow permanently.`
- : "Delete this workflow."}
+ ? `"${workflow.name}" will stop triggering and be removed permanently.`
+ : "This workflow will be removed permanently."}
@@ -51,7 +51,7 @@ export function WorkflowDeleteDialog({
type="button"
variant="destructive"
>
- Delete
+ Delete workflow
diff --git a/desktop/src/shared/lib/clipboard.ts b/desktop/src/shared/lib/clipboard.ts
index 93e2bed44e..25a06fa259 100644
--- a/desktop/src/shared/lib/clipboard.ts
+++ b/desktop/src/shared/lib/clipboard.ts
@@ -17,6 +17,6 @@ export function copyTextToClipboard(
toast.success(successMessage);
})
.catch(() => {
- toast.error("Failed to copy to clipboard");
+ toast.error("Couldn't copy to clipboard");
});
}
diff --git a/desktop/src/shared/lib/localStorageQuota.ts b/desktop/src/shared/lib/localStorageQuota.ts
index bf194a6cc8..39dab9f1a5 100644
--- a/desktop/src/shared/lib/localStorageQuota.ts
+++ b/desktop/src/shared/lib/localStorageQuota.ts
@@ -38,9 +38,9 @@ function notifyStorageFull(): void {
// Dynamic import keeps this module usable from node unit tests.
import("sonner")
.then(({ toast }) => {
- toast.error("Local storage is full", {
+ toast.error("Storage is full", {
description:
- "Buzz could not save some local data — read positions may not persist across restarts.",
+ "Buzz couldn't save some data. Recent changes may be lost when you restart.",
});
})
.catch(() => {});
diff --git a/desktop/src/shared/ui/markdown.tsx b/desktop/src/shared/ui/markdown.tsx
index b1f9623f3e..6afe400ea6 100644
--- a/desktop/src/shared/ui/markdown.tsx
+++ b/desktop/src/shared/ui/markdown.tsx
@@ -1165,7 +1165,7 @@ function ImageBlock({ alt, dim, resolvedSrc, src, thumbSrc }: ImageBlockProps) {
toast.success("Copied to clipboard");
})
.catch((err: unknown) => {
- const msg = err instanceof Error ? err.message : "Copy failed";
+ const msg = err instanceof Error ? err.message : "Couldn't copy";
toast.error(msg);
});
}, []);
@@ -1176,7 +1176,7 @@ function ImageBlock({ alt, dim, resolvedSrc, src, thumbSrc }: ImageBlockProps) {
if (!downloadSrc) return;
invokeTauri("download_image", { url: downloadSrc }).catch(
(err: unknown) => {
- const msg = err instanceof Error ? err.message : "Download failed";
+ const msg = err instanceof Error ? err.message : "Couldn't download";
toast.error(msg);
},
);
@@ -1332,7 +1332,7 @@ function ExternalLinkAnchor({
onSelect: () => {
closeMenu();
void openUrl(href).catch(() => {
- toast.error("Failed to open link");
+ toast.error("Couldn't open link");
});
},
},
diff --git a/desktop/src/shared/ui/markdown/CodeBlock.tsx b/desktop/src/shared/ui/markdown/CodeBlock.tsx
index 06f9fb4c4b..faa3777d61 100644
--- a/desktop/src/shared/ui/markdown/CodeBlock.tsx
+++ b/desktop/src/shared/ui/markdown/CodeBlock.tsx
@@ -87,7 +87,7 @@ export function MarkdownCodeBlock({
toast.success("Copied code to clipboard");
} catch (error) {
console.error("Failed to copy code block", error);
- toast.error("Failed to copy code");
+ toast.error("Couldn't copy code");
} finally {
setIsCopying(false);
}
diff --git a/desktop/src/shared/ui/markdown/FileCard.tsx b/desktop/src/shared/ui/markdown/FileCard.tsx
index 889847193e..4015662e34 100644
--- a/desktop/src/shared/ui/markdown/FileCard.tsx
+++ b/desktop/src/shared/ui/markdown/FileCard.tsx
@@ -49,7 +49,8 @@ export function FileCard({
onClick={() => {
invokeTauri("download_file", { url: href, filename }).catch(
(err: unknown) => {
- const msg = err instanceof Error ? err.message : "Download failed";
+ const msg =
+ err instanceof Error ? err.message : "Couldn't download";
toast.error(msg);
},
);
diff --git a/desktop/src/shared/ui/useVideoContextMenu.tsx b/desktop/src/shared/ui/useVideoContextMenu.tsx
index ec6c5791f7..91f1998dd7 100644
--- a/desktop/src/shared/ui/useVideoContextMenu.tsx
+++ b/desktop/src/shared/ui/useVideoContextMenu.tsx
@@ -55,7 +55,9 @@ export function useVideoContextMenu(
url: downloadUrl,
filename: resolveVideoDownloadFilename(filename),
}).catch((err: unknown) => {
- toast.error(err instanceof Error ? err.message : "Download failed");
+ toast.error(
+ err instanceof Error ? err.message : "Couldn't download",
+ );
});
},
});
diff --git a/desktop/tests/e2e/agent-lifecycle-feedback.spec.ts b/desktop/tests/e2e/agent-lifecycle-feedback.spec.ts
index 6200975889..f0e5cce851 100644
--- a/desktop/tests/e2e/agent-lifecycle-feedback.spec.ts
+++ b/desktop/tests/e2e/agent-lifecycle-feedback.spec.ts
@@ -1,8 +1,8 @@
/**
* E2E screenshots + regression tests for agent-lifecycle feedback (PR #1766):
*
- * 1. Persona delete confirm dialog shows "Also deletes N agent instance(s)."
- * when the persona has linked managed-agent instances.
+ * 1. Persona delete confirm dialog discloses that N linked agent instance(s)
+ * are also deleted when the persona has linked managed-agent instances.
* 2. Global-config save reports "Saved. Restarted N agents." when running agents
* were restarted.
* 3. Global-config save reports plain "Saved." when no agents were restarted;
@@ -75,7 +75,7 @@ test.describe("agent lifecycle feedback screenshots", () => {
});
});
- // Shot 01: persona delete confirm dialog — "Also deletes 2 agent instance(s)."
+ // Shot 01: persona delete confirm dialog — 2 linked agent instances.
// Seeds a custom persona with two linked managed agents so instanceCount = 2.
// Triggers the delete confirm from the persona's "..." actions menu.
test("01-delete-cascade-copy", async ({ page }) => {
@@ -124,9 +124,9 @@ test.describe("agent lifecycle feedback screenshots", () => {
await expect(dialog).toBeVisible({ timeout: 5_000 });
// Core assertion: the cascade copy shows the correct instance count
- // (plural) and discloses the relay-side archival (PR #2135).
+ // (plural) and discloses the identity archival (PR #2135).
await expect(dialog).toContainText(
- "Also deletes 2 agent instances and archives their identities on the relay",
+ "Its 2 agent instances are also deleted and their identities archived in the community",
);
await waitForAnimations(page);
@@ -215,7 +215,7 @@ test.describe("agent lifecycle feedback screenshots", () => {
});
});
- // Shot 04: persona delete confirm dialog — singular "Also deletes 1 agent instance."
+ // Shot 04: persona delete confirm dialog — singular 1 linked agent instance.
// One linked instance → singular copy (no extra "s").
test("04-delete-cascade-singular", async ({ page }) => {
await installMockBridge(page, {
@@ -253,7 +253,7 @@ test.describe("agent lifecycle feedback screenshots", () => {
// Singular copy ("instance", "its identity") plus the archival disclosure.
await expect(dialog).toContainText(
- "Also deletes 1 agent instance and archives its identity on the relay",
+ "Its 1 agent instance is also deleted and its identity archived in the community",
);
await waitForAnimations(page);
@@ -263,7 +263,7 @@ test.describe("agent lifecycle feedback screenshots", () => {
});
// Shot 05: persona delete confirm dialog — zero linked instances.
- // No managed agents linked to the persona → "Also deletes…" line absent.
+ // No managed agents linked to the persona → cascade line absent.
test("05-delete-cascade-zero-instances", async ({ page }) => {
await installMockBridge(page, {
personas: [
@@ -292,7 +292,7 @@ test.describe("agent lifecycle feedback screenshots", () => {
await expect(dialog).toBeVisible({ timeout: 5_000 });
// No linked instances → no cascade warning.
- await expect(dialog).not.toContainText("Also deletes");
+ await expect(dialog).not.toContainText("agent instance");
});
// Shot 06: global config save — singular "Saved. Restarted 1 agent."