| name | Linear Attachments |
| description | This skill should be used when uploading files to Linear, linking external URLs as attachments, or downloading existing attachments with auth. Activates on "linear attachment", "linear file upload", "fileUpload mutation", "attachmentLinkCreate". |
| version | 1.0.0 |
| allowed-tools | ["Read","Grep","Glob","Bash"] |
Linear Attachments
References:
Two flavours
| Type | Storage | Use case |
|---|
| File attachment | Linear S3 (pre-signed) | screenshots, logs, design files |
| Link attachment | External URL only | GitHub PR, Figma, Notion, Loom |
File upload (3-step)
const reservation = await client.fileUpload({
contentType: "image/png",
filename: "screenshot.png",
size: file.length
});
await fetch(reservation.uploadUrl, {
method: "PUT",
body: file,
headers: Object.fromEntries(reservation.headers.map(h => [h.key, h.value]))
});
await client.attachmentCreate({
issueId,
url: reservation.assetUrl,
title: "Screenshot",
contentType: "image/png"
});
Helper in lib/attachment-upload.ts:
export async function uploadFileToLinear(
client: LinearClient,
issueId: string,
filePath: string,
title?: string
): Promise<string>;
Multipart for large files
For files >50MB:
- Linear's pre-signed URL supports multipart S3 uploads
- Split into 5MB parts, PUT each with
partNumber query param
- Complete with
POST ?uploads to finalise
Most use cases stay under 50MB; only logs and video do this.
Link attachments
await client.attachmentLinkCreate(issueId, "https://github.com/org/repo/pull/42", "PR #42");
Linear infers preview from URL pattern. Supported: GitHub PR / issue / commit, Figma, Notion, Loom, Vimeo, Slack thread, generic OG-rich pages.
Download with auth
Asset URLs require the same Linear token in Authorization: Bearer <token>. Don't share these URLs publicly — they expire after 7 days but exposing during that window is a leak.
const res = await fetch(assetUrl, {
headers: { Authorization: `Bearer ${process.env.LINEAR_API_KEY}` }
});
const buffer = Buffer.from(await res.arrayBuffer());
Or, mint a short-lived signed URL through your own service if you need to share with end users.
Bridge fan-out
- Harness Code: file attachments are linked (not copied) to the linked PR via a comment with the asset URL — the URL is auth-required, so reviewers must be Linear members.
- MS Planner: attachments uploaded to Linear are mirrored to OneDrive/SharePoint via Microsoft Graph
driveItem upload. The Planner task references field gets the OneDrive URL.
Security notes
- Validate content-type before declaring it (don't trust user input)
- Cap upload size at the layer above (usually 100MB)
- Strip EXIF from images if client-side is feasible
- Don't pass user file bytes through your backend; redirect them to Linear's pre-signed URL directly