Web UI: paperclip button for file upload (images, PDFs, text), inline attachment cards with file icon/name/size, image thumbnails with fullscreen overlay, attachment display in thread panel. Threads: always-visible reply count badges on messages, clickable to open thread panel. reply_count and attachments enriched in all API responses via batch queries. MCP: attachments parameter on send_message tool, updated tool descriptions for threading and attachment workflow guidance. Backend: file type validation (allowlist), AttachmentLinker interface to avoid circular deps, GetReplyCounts batch query, EnrichMessages method on MessagingService. Admin CLI: synapbus attachments backup/restore with tar.gz archives, dedup-safe restore. 24 new test cases across 4 packages. All 24 test packages pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.3 KiB
Autonomous Implementation Summary: Attachments & Threads Enhancement
Branch: 009-attachments-threads
Date: 2026-03-17
Status: Complete
What Was Built
Attachments (Web UI + MCP + Admin CLI)
-
Web UI file upload: Users can attach files (images, PDFs, text files) when composing messages via a paperclip button in the compose form. Uploaded files show as chips with remove buttons.
-
Attachment display: Image attachments render as thumbnails (200x200px max) inline with messages. Clicking opens a fullscreen overlay with close (Escape, click-outside, X button) and download. Non-image files show as file icons with filename, size, and download link.
-
MCP agent support: Agents can attach files by uploading via
upload_attachmentaction and passing hashes in the newattachmentsparameter onsend_message. Tool descriptions updated to document the workflow. -
File type validation: Upload restricted to images (jpg, png, gif, webp, svg), PDFs, and text files (txt, md, csv, json, xml, yaml, log). Invalid types rejected with clear error.
-
Admin backup/restore:
synapbus attachments backup --output path.tar.gzandsynapbus attachments restore --input path.tar.gzcommands. Restore is dedup-safe (skips existing files).
Threads
-
Thread visibility: Messages with replies show an always-visible "N replies" badge with a chat bubble icon. Clicking opens the thread panel.
-
Reply count in API: All message API responses now include
reply_count(batch-loaded via efficient GROUP BY query). -
MCP threading:
reply_toparameter description updated to clearly guide agents on threading behavior. Thread context visible in MCP responses. -
Attachment display in threads: Thread panel also renders attachment thumbnails/file icons.
Files Modified
Backend (Go)
| File | Changes |
|---|---|
internal/messaging/types.go |
Added AttachmentInfo struct, ReplyCount, Attachments fields to Message |
internal/messaging/options.go |
Added Attachments []string to SendOptions |
internal/messaging/store.go |
Added GetReplyCounts batch query method + interface |
internal/messaging/service.go |
Added AttachmentLinker interface, EnrichMessages, attachment linking in SendMessage |
internal/attachments/model.go |
Added ErrUnsupportedType error |
internal/attachments/mime.go |
Added IsAllowedType function |
internal/attachments/service.go |
Added file type validation in Upload |
internal/api/messages_handler.go |
Accept attachments[] in send, EnrichMessages in all handlers |
internal/mcp/tools_hybrid.go |
Added attachments param to send_message, updated descriptions, enrich responses |
internal/mcp/bridge.go |
Handle attachments in callSendMessage, callSendChannelMessage |
internal/channels/service.go |
Added attachments param to BroadcastMessage |
internal/actions/registry.go |
Updated upload_attachment description |
cmd/synapbus/main.go |
Added attachmentLinkerAdapter, wired into messaging service |
cmd/synapbus/admin.go |
Added backup and restore subcommands |
Frontend (Svelte)
| File | Changes |
|---|---|
web/src/lib/api/client.ts |
Added attachments.upload(), attachments param in messages.send() |
web/src/lib/components/ComposeForm.svelte |
Attachment upload button, file picker, preview chips |
web/src/lib/components/AttachmentPreview.svelte |
NEW — thumbnail + fullscreen overlay component |
web/src/lib/components/MessageList.svelte |
Attachment display, thread reply count badges |
web/src/lib/components/ThreadPanel.svelte |
Attachment display in thread messages |
Tests
| File | New Tests |
|---|---|
internal/messaging/store_test.go |
TestSQLiteMessageStore_GetReplyCounts (4 subtests) |
internal/messaging/service_test.go |
TestMessagingService_EnrichMessages (3 subtests) |
internal/attachments/mime_test.go |
TestIsAllowedType (12 cases) |
internal/attachments/service_test.go |
TestService_Upload_FileTypeValidation (5 cases) |
internal/channels/service_test.go |
Updated 13 call sites for new BroadcastMessage signature |
Test Results
- Go tests: 25 packages, all pass, 0 failures
- Integration tests: 9 E2E tests, all pass
- New tests: 24 test cases added, all pass
- Web build: Svelte SPA builds successfully
- Binary build: 90MB arm64 binary compiles cleanly
Architecture Decisions
- No circular dependencies: Used
AttachmentLinkerinterface + adapter pattern to avoid messaging->attachments import - Batch loading: Reply counts loaded via single GROUP BY query; attachments loaded per-message (acceptable for LAN scale)
- Client-side thumbnails: CSS-only resizing (no server-side image processing, preserves zero-CGO constraint)
- Zero new migrations: Leveraged existing
reply_tocolumn (migration 007) andattachmentstable (migration 001) - Zero new dependencies: All using Go stdlib + existing libraries
Constitution Compliance
All 10 principles satisfied:
- I. Local-First: No external dependencies added
- II. MCP-Native: Agent features use MCP tools exclusively
- III. Pure Go, Zero CGO: stdlib archive/tar + compress/gzip for backup
- X. Web UI First-Class: Full attachment and thread UI experience