feat(app): unify composer attachments with pill + lightbox redesign

Images and GitHub issues/PRs now live in one draft-store list (ComposerAttachment union) with cwd persisted on the draft. Paperclip becomes a + drop-up menu; queue button removed. Each pill uses a shared AttachmentPill wrapper with a corner-X that mirrors the auto-update toast spec. Pill body opens the attachment: GitHub via openExternalUrl, images via a new fullscreen AttachmentLightbox. GitHub picker auto-closes on select.
This commit is contained in:
Mohamed Boudra
2026-04-17 11:36:08 +07:00
parent 11524dc349
commit 3838a8b969
25 changed files with 2994 additions and 735 deletions
+8 -5
View File
@@ -4,7 +4,7 @@ import type { DaemonClient } from "@server/client/daemon-client";
import type { AgentDirectoryEntry } from "@/types/agent-directory";
import type { StreamItem } from "@/types/stream";
import type { PendingPermission } from "@/types/shared";
import type { AttachmentMetadata } from "@/attachments/types";
import type { ComposerAttachment } from "@/attachments/types";
import type { AgentLifecycleStatus } from "@server/shared/agent-lifecycle";
import type {
AgentPermissionResponse,
@@ -263,7 +263,10 @@ export interface SessionState {
fileExplorer: Map<string, AgentFileExplorerState>;
// Queued messages
queuedMessages: Map<string, Array<{ id: string; text: string; images?: AttachmentMetadata[] }>>;
queuedMessages: Map<
string,
Array<{ id: string; text: string; attachments: ComposerAttachment[] }>
>;
}
// Global store state
@@ -379,10 +382,10 @@ interface SessionStoreActions {
setQueuedMessages: (
serverId: string,
value:
| Map<string, Array<{ id: string; text: string; images?: AttachmentMetadata[] }>>
| Map<string, Array<{ id: string; text: string; attachments: ComposerAttachment[] }>>
| ((
prev: Map<string, Array<{ id: string; text: string; images?: AttachmentMetadata[] }>>,
) => Map<string, Array<{ id: string; text: string; images?: AttachmentMetadata[] }>>),
prev: Map<string, Array<{ id: string; text: string; attachments: ComposerAttachment[] }>>,
) => Map<string, Array<{ id: string; text: string; attachments: ComposerAttachment[] }>>),
) => void;
// Hydration