Skip to content
Draft
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 3 additions & 3 deletions desktop/src/features/agents/ui/AgentInstanceEditDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: () => {
Expand All @@ -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}`,
),
});
},
Expand Down
12 changes: 6 additions & 6 deletions desktop/src/features/agents/ui/PersonaDeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -76,7 +76,7 @@ export function PersonaDeleteDialog({
type="button"
variant="destructive"
>
Delete
Delete agent
</Button>
</AlertDialogAction>
</AlertDialogFooter>
Expand Down
6 changes: 3 additions & 3 deletions desktop/src/features/agents/ui/TeamDeleteDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ export function TeamDeleteDialog({
<AlertDialogTitle>Delete team?</AlertDialogTitle>
<AlertDialogDescription>
{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."}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
Expand All @@ -51,7 +51,7 @@ export function TeamDeleteDialog({
type="button"
variant="destructive"
>
Delete
Delete team
</Button>
</AlertDialogAction>
</AlertDialogFooter>
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/features/agents/useOpenAgentActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 14 additions & 3 deletions desktop/src/features/channel-templates/useApplyTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`,
);
}
}
Expand Down
13 changes: 11 additions & 2 deletions desktop/src/features/channels/ui/MembersSidebarMemberCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -439,6 +447,7 @@ function MemberActionsMenu({
onTimeout(
member,
Math.floor(Date.now() / 1000) + preset.seconds,
preset.label,
)
}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
);
}
},
Expand All @@ -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],
);
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/features/chat/ui/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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",
);
}
}
Expand All @@ -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",
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/features/communities/useNestNotifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const MIGRATION_TOAST_KEY = "buzz-legacy-nest-migrated-notified";
export function useNestNotifications(): void {
useEffect(() => {
const unlistenReposError = listen<string>("repos-dir-error", (event) => {
toast.error("Repos directory not applied", {
toast.error("Couldn't apply the repos directory", {
description: event.payload,
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
);
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
);
}
}
Expand Down Expand Up @@ -196,7 +194,7 @@ function RelayMemberRow({
pubkey: member.pubkey,
role: "admin",
}),
"Promoted relay admin",
`Promoted ${displayName} to admin`,
)
}
size="icon"
Expand All @@ -218,7 +216,7 @@ function RelayMemberRow({
pubkey: member.pubkey,
role: "member",
}),
"Demoted to relay member",
`Demoted ${displayName} to member`,
)
}
size="icon"
Expand All @@ -237,7 +235,7 @@ function RelayMemberRow({
onClick={() =>
void mutateWithToast(
() => removeMutation.mutateAsync(member.pubkey),
"Removed relay member",
`Removed ${displayName} from the community`,
)
}
size="icon"
Expand Down Expand Up @@ -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",
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export function ConfirmRemoveDialog({
<DialogHeader>
<DialogTitle>Remove {label}?</DialogTitle>
<DialogDescription>
This will immediately revoke their access to the relay.
This will immediately revoke their access to the community.
</DialogDescription>
{member ? (
<PubKey
Expand Down Expand Up @@ -75,7 +75,7 @@ export function ConfirmRemoveDialog({
toast.error(
error instanceof Error
? error.message
: "Failed to remove member",
: "Couldn't remove member",
);
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function CustomEmojiSettingsCard() {
return;
}
if (!blob.type.startsWith("image/")) {
toast.error("Choose an image file for custom emoji.");
toast.error("Choose an image file for custom emoji");
return;
}
setPendingUpload({ url: blob.url, filename: blob.filename ?? null });
Expand All @@ -74,9 +74,7 @@ export function CustomEmojiSettingsCard() {
}
} catch (error) {
toast.error(
error instanceof Error
? error.message
: "Failed to upload emoji image.",
error instanceof Error ? error.message : "Couldn't upload emoji image",
);
} finally {
setIsUploading(false);
Expand All @@ -95,7 +93,7 @@ export function CustomEmojiSettingsCard() {
toast.success(`Added :${stored}:`);
} catch (error) {
toast.error(
error instanceof Error ? error.message : "Failed to add emoji.",
error instanceof Error ? error.message : "Couldn't add emoji",
);
}
}, [normalized, pendingUpload, setEmoji]);
Expand All @@ -112,7 +110,7 @@ export function CustomEmojiSettingsCard() {
toast.success(`Removed :${shortcode}:`);
} catch (error) {
toast.error(
error instanceof Error ? error.message : "Failed to remove emoji.",
error instanceof Error ? error.message : "Couldn't remove emoji",
);
}
},
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/features/forum/ui/DeleteConfirmDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function DeleteConfirmDialog({
<AlertDialogHeader>
<AlertDialogTitle>Delete {label}?</AlertDialogTitle>
<AlertDialogDescription>
This will permanently delete this {label} and cannot be undone.
This will permanently delete this {label} and can't be undone.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading