Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
497006f
chore(desktop): polish reply design surfaces
thomaspblock Apr 14, 2026
17abe0c
Merge main into reply-design
thomaspblock Apr 16, 2026
1246741
fix(desktop): polish timeline spacing and panel chrome
thomaspblock Apr 16, 2026
77a2e3b
Merge main into reply-design
thomaspblock Apr 30, 2026
f214bb9
Polish message timeline affordances
thomaspblock May 1, 2026
607c77d
Polish message date divider
thomaspblock May 4, 2026
bb90576
Fix thread reply pill behavior
thomaspblock May 4, 2026
57b10f3
Update thread smoke coverage
thomaspblock May 4, 2026
11998b1
Fix sticky date divider handoff
thomaspblock May 4, 2026
cfaf3b5
Merge main into reply-design
thomaspblock May 4, 2026
e40d4e7
Align active agent pill with timeline text
thomaspblock May 4, 2026
5a675de
Fix desktop Biome cleanup after merge
thomaspblock May 5, 2026
a794776
Align system message reactions
thomaspblock May 5, 2026
1e6b579
Refine message timeline spacing
thomaspblock May 5, 2026
8def39a
Anchor agent activity to messages
thomaspblock May 5, 2026
8c0ba24
Merge remote-tracking branch 'origin/main' into reply-design
thomaspblock May 5, 2026
96035eb
Move agent activity into composer
thomaspblock May 6, 2026
a981831
Merge branch 'main' into reply-design
thomaspblock May 6, 2026
4433e47
Fix composer activity type fallback
thomaspblock May 6, 2026
4188f31
Fix desktop header and popover smoke checks
thomaspblock May 6, 2026
65da46d
Prevent profile popover from reopening on panel click
thomaspblock May 6, 2026
052c2f4
Update thread composer activity and header hover copy
thomaspblock May 6, 2026
99beb2c
Show ephemeral header badge as icon only
thomaspblock May 7, 2026
8ee5db0
Fix ephemeral badge smoke expectations
thomaspblock May 7, 2026
4877ee2
Fix duplicate video playback (#492)
thomaspblock May 7, 2026
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: 2 additions & 1 deletion desktop/scripts/check-file-sizes.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const overrides = new Map([
["src/app/AppShell.tsx", 860], // message edit state + handlers + ChannelPane edit prop threading + scrollback pagination + workflows view + memory-leak safeguards
["src/features/channels/hooks.ts", 550], // canvas query + mutation hooks + DM hide mutation
["src/features/channels/ui/ChannelManagementSheet.tsx", 800],
["src/features/channels/ui/ChannelScreen.tsx", 530], // profile panel state + mutual exclusion wiring + ProfilePanelProvider context
["src/features/channels/ui/ChannelPane.tsx", 520], // composer/timeline/sidebar orchestration + anchored agent activity footers
["src/features/channels/ui/ChannelScreen.tsx", 550], // profile panel state + mutual exclusion wiring + ProfilePanelProvider context + agent typing classification
["src/features/messages/hooks.ts", 500], // message query/mutation hooks + optimistic updates
["src/features/messages/ui/MessageComposer.tsx", 700], // media upload handlers (paste, drop, dialog) + channelId reset effect + edit mode (pre-fill, save, cancel, escape)
["src/features/settings/ui/SettingsView.tsx", 600],
Expand Down
156 changes: 86 additions & 70 deletions desktop/src/features/agents/ui/PersonaCatalogDetailsSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { isCatalogPersonaSelected } from "@/features/agents/lib/catalog";
import { ProfileAvatar } from "@/features/profile/ui/ProfileAvatar";
import type { AgentPersona } from "@/shared/api/types";
import { Card } from "@/shared/ui/card";
import { cn } from "@/shared/lib/cn";
import { promptPreview } from "@/shared/lib/promptPreview";
import {
Expand All @@ -19,6 +18,8 @@ import {
} from "./personaLibraryCopy";

type PersonaCatalogDetailsSheetProps = {
feedbackErrorMessage: string | null;
feedbackNoticeMessage: string | null;
isPending: boolean;
onOpenChange: (open: boolean) => void;
onTogglePersona: (persona: AgentPersona) => void;
Expand All @@ -27,6 +28,8 @@ type PersonaCatalogDetailsSheetProps = {
};

export function PersonaCatalogDetailsSheet({
feedbackErrorMessage,
feedbackNoticeMessage,
isPending,
onOpenChange,
onTogglePersona,
Expand All @@ -40,12 +43,12 @@ export function PersonaCatalogDetailsSheet({
return (
<Sheet onOpenChange={onOpenChange} open={open}>
<SheetContent
className="w-full overflow-y-auto sm:max-w-xl"
className="flex w-full flex-col gap-0 overflow-hidden bg-background p-0 sm:max-w-xl"
data-testid="persona-catalog-details-sheet"
>
{persona ? (
<div className="space-y-6 pr-4">
<SheetHeader className="border-b border-border/60 pb-4 pr-10">
<>
<SheetHeader className="relative z-10 space-y-4 bg-background/25 px-6 py-6 pr-16 text-left shadow-[0_4px_24px_rgba(0,0,0,0.06)] backdrop-blur-xl supports-[backdrop-filter]:bg-background/20 dark:shadow-[0_4px_24px_rgba(0,0,0,0.25)]">
<div className="flex items-start gap-3">
<ProfileAvatar
avatarUrl={persona.avatarUrl}
Expand All @@ -65,81 +68,94 @@ export function PersonaCatalogDetailsSheet({
</div>
</div>
</SheetHeader>
<div className="flex-1 space-y-6 overflow-y-auto px-6 py-6">
<button
aria-label={getPersonaCatalogSelectionAriaLabel(
persona.displayName,
isSelected,
)}
aria-pressed={isSelected}
className={cn(
"w-full rounded-xl border p-4 text-left transition-[background-color,border-color,box-shadow] focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2",
isSelected
? "border-primary bg-primary/10 text-foreground"
: "border-border/80 bg-background/60 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
isPending && "cursor-not-allowed opacity-70",
)}
data-state={isSelected ? "selected" : "available"}
data-testid={`persona-catalog-detail-selection-target-${persona.id}`}
disabled={isPending}
onClick={() => {
onTogglePersona(persona);
}}
type="button"
>
<div className="flex items-start justify-between gap-4">
<div>
<p
className="text-sm font-semibold tracking-tight"
data-testid="persona-catalog-detail-selection-title"
>
{selectionCopy.title}
</p>
<p
className="mt-1 text-sm text-muted-foreground"
data-testid="persona-catalog-detail-selection-description"
>
{selectionCopy.description}
</p>
</div>
<PersonaCatalogSelectionBadge isActive={isSelected} />
</div>
</button>

{feedbackNoticeMessage ? (
<p className="rounded-2xl border border-primary/20 bg-primary/10 px-4 py-3 text-sm text-primary">
{feedbackNoticeMessage}
</p>
) : null}

{feedbackErrorMessage ? (
<p className="rounded-2xl border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
{feedbackErrorMessage}
</p>
) : null}

<button
aria-label={getPersonaCatalogSelectionAriaLabel(
persona.displayName,
isSelected,
)}
aria-pressed={isSelected}
className={cn(
"w-full rounded-xl border p-4 text-left transition-[background-color,border-color,box-shadow] focus:outline-none focus-visible:ring-2 focus-visible:ring-primary/40 focus-visible:ring-offset-2",
isSelected
? "border-primary bg-primary/10 text-foreground"
: "border-border/80 bg-background/60 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
isPending && "cursor-not-allowed opacity-70",
)}
data-state={isSelected ? "selected" : "available"}
data-testid={`persona-catalog-detail-selection-target-${persona.id}`}
disabled={isPending}
onClick={() => {
onTogglePersona(persona);
}}
type="button"
>
<div className="flex items-start justify-between gap-4">
<div>
<p
className="text-sm font-semibold tracking-tight"
data-testid="persona-catalog-detail-selection-title"
>
{selectionCopy.title}
<div className="grid gap-3 sm:grid-cols-2">
<div className="rounded-xl border border-border/70 bg-card/70 p-4">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Type
</p>
<p className="mt-2 text-sm font-medium">Built-in persona</p>
</div>
<div className="rounded-xl border border-border/70 bg-card/70 p-4">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Preferred model
</p>
<p
className="mt-1 text-sm text-muted-foreground"
data-testid="persona-catalog-detail-selection-description"
>
{selectionCopy.description}
<p className="mt-2 text-sm font-medium">
{persona.model ?? "Use app default"}
</p>
</div>
<div className="rounded-xl border border-border/70 bg-card/70 p-4 sm:col-span-2">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Preferred provider
</p>
<p className="mt-2 text-sm font-medium">
{persona.provider ?? "Use app default"}
</p>
</div>
<PersonaCatalogSelectionBadge isActive={isSelected} />
</div>
</button>

<div className="grid gap-3 sm:grid-cols-2">
<Card className="p-4">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Type
</p>
<p className="mt-2 text-sm font-medium">Built-in persona</p>
</Card>
<Card className="p-4">
<div className="rounded-xl border border-border/70 bg-card/70 p-4">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Preferred model
System prompt
</p>
<p className="mt-2 text-sm font-medium">
{persona.model ?? "Use app default"}
</p>
</Card>
<Card className="p-4 sm:col-span-2">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
Preferred provider
</p>
<p className="mt-2 text-sm font-medium">
{persona.provider ?? "Use app default"}
</p>
</Card>
<pre className="mt-3 whitespace-pre-wrap break-words font-sans text-sm leading-6 text-foreground">
{persona.systemPrompt}
</pre>
</div>
</div>

<Card className="p-4">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
System prompt
</p>
<pre className="mt-3 whitespace-pre-wrap break-words font-sans text-sm leading-6 text-foreground">
{persona.systemPrompt}
</pre>
</Card>
</div>
</>
) : null}
</SheetContent>
</Sheet>
Expand Down
2 changes: 2 additions & 0 deletions desktop/src/features/agents/ui/PersonaCatalogSurface.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export function PersonaCatalogSurface({
/>

<PersonaCatalogDetailsSheet
feedbackErrorMessage={feedbackErrorMessage}
feedbackNoticeMessage={feedbackNoticeMessage}
isPending={isPending}
onOpenChange={(open) => {
if (!open) {
Expand Down
Loading
Loading