Merge PR #120: document attachment previews + thumbnails (COD-38)

Adds attachment cards with first-page thumbnails and inline document
previews (PDF/Office via pdftoppm + LibreOffice), plus review hardening
(converter concurrency limiter, bounded preview cache, fixed detected-doc
preview routing). See PR #120.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

# Conflicts:
#	src/web/public/styles.css
This commit is contained in:
Claude (Codeman maintainer)
2026-06-14 08:49:36 +02:00
15 changed files with 1509 additions and 17 deletions
+7 -2
View File
@@ -60,7 +60,7 @@ import {
type SubagentToolResult,
} from '../subagent-watcher.js';
import { imageWatcher } from '../image-watcher.js';
import { attachmentRegistry, registerExternalAttachment } from '../attachment-registry.js';
import { attachmentRegistry, buildFileThumbnailRoute, registerExternalAttachment } from '../attachment-registry.js';
import { TranscriptWatcher } from '../transcript-watcher.js';
import { TeamWatcher } from '../team-watcher.js';
import { TunnelManager } from '../tunnel-manager.js';
@@ -442,7 +442,12 @@ export class WebServer extends EventEmitter {
this.imageWatcherHandlers = {
detected: (event: ImageDetectedEvent) => this.broadcast(SseEvent.ImageDetected, event),
attachmentDetected: (event: AttachmentDetectedEvent) =>
this.broadcast(SseEvent.AttachmentDetected, { ...event, source: event.source || 'detected' }),
this.broadcast(SseEvent.AttachmentDetected, {
...event,
source: event.source || 'detected',
thumbnailUrl:
event.thumbnailUrl || buildFileThumbnailRoute(event.sessionId, event.relativePath || event.fileName),
}),
error: (error: Error, sessionId?: string) => {
console.error(`[ImageWatcher] Error${sessionId ? ` for ${sessionId}` : ''}:`, error.message);
},