<!-- source-hash: aa7997b65102b2c65fd293fc9f3faa3d -->
Manages the upload state machine for chat file attachments, handling multi-file staging, magic-byte MIME validation, progress tracking, and per-file abort control before sending messages.

## Key Components

### `StagedAttachment`
Internal state shape for each file in the upload pipeline. Tracks `id`, `file`, `status` (`sniffing | uploading | ready | error`), `progress` (0–100), `storagePath`, `viewToken`, and `errorMessage`.

### `uploadWithProgress(url, file, token, onProgress?, signal?)`
Inline XHR helper that PUTs file bytes to a Supabase signed URL. Maps raw network progress to the 10–95 range, supports `AbortSignal` cancellation, and handles timeout/error/abort events with proper cleanup.

### `useChatAttachments()`
Primary hook exposing `UseChatAttachmentsApi`:

| Member | Description |
|---|---|
| `attachments` | Full staged array with state-machine metadata |
| `readyAttachments` | Wire-format `ChatAttachment[]` for `sendMessage` |
| `hasInflightUploads` | `true` while any upload is in-progress (disables Send) |
| `addFiles(files)` | Stages and begins uploading files; deduplicates by `(name, size, lastModified)` |
| `removeAttachment(id)` | Aborts in-flight XHR and removes the file |
| `clear()` | Aborts all controllers and resets state |

## Usage Example

```typescript
const {
  attachments,
  readyAttachments,
  hasInflightUploads,
  addFiles,
  removeAttachment,
  clear,
} = useChatAttachments()

// Stage files from an input element
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  if (e.target.files) addFiles(e.target.files)
}

// Pass ready attachments when sending
await sendMessage(text, { pendingAttachments: readyAttachments })

// Abort a specific upload mid-flight
removeAttachment(attachmentId)
```

> **Security note:** Files are validated via magic-byte sniffing (`file-type`) before upload, rejecting extension spoofs (e.g. `evil.exe` renamed `screenshot.png`). The sniffed MIME — not `file.type` — is sent to the server for URL minting.