When a channel bridge passes an attachment without an explicit `name`,
extractAttachmentFiles fell back to `attachment-<ts>` with no extension.
Agents could not tell whether the file was a JPEG, PDF, or audio clip,
and tools keyed on extension (image viewers, exiftool, etc.) misbehaved.
Two cases are now covered:
1. Channels that set `mimeType` but no `name` (Discord/Slack documents,
Telegram document uploads). A small MIME-to-extension table covers
the common content types — image/*, audio/*, video/*, pdf, zip,
txt, json. Unknown MIMEs fall back to the unsuffixed name.
2. Channels that set `att.type` but no `mimeType` (Telegram photos,
stickers, voice, animations). The chat-sdk bridge sets a coarse
media-class (`photo` / `sticker` / `voice` / `video` /
`animation`) which is reliable enough to derive a canonical
extension. Telegram GIFs are MP4 under the hood.
The existing isSafeAttachmentName security guard is preserved — the
derived name still passes through it before disk I/O. The new lookup
tables emit static values from internal maps and cannot construct a
path-traversal payload; attacker-controlled att.name continues to flow
through the same validator.