import { bundledLanguagesInfo } from "shiki" import { getFilename } from "@opencode-ai/core/util/path" import type { FilePart } from "@opencode-ai/sdk/v2" export function attached(part: FilePart) { return part.url.startsWith("data:") } export function inline(part: FilePart) { if (attached(part)) return false return part.source?.text?.start !== undefined && part.source?.text?.end !== undefined } export function kind(part: FilePart) { return part.mime.startsWith("image/") ? "image" : "file" } // language metadata only; grammars stay behind shiki's lazy imports const LANGUAGE_NAMES = new Map( bundledLanguagesInfo.flatMap((info) => [info.id, ...(info.aliases ?? [])].map((alias) => [alias, info.name] as [string, string]), ), ) // attachments carry text/plain for all text files, so the label comes from the extension; // filename may be an absolute path, so extract the basename before looking for one export function typeLabel(filename: string, mime: string) { if (mime === "application/pdf") return "PDF" const base = getFilename(filename) // idx 0 is a dotfile like .gitignore, not an extension const idx = base.lastIndexOf(".") const suffix = idx <= 0 ? "" : base.slice(idx + 1).toLowerCase() if (!suffix) return "File" return LANGUAGE_NAMES.get(suffix) ?? suffix.toUpperCase() }