import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { cn } from "@/lib/utils";
type FileReferenceKind =
| "default"
| "css"
| "html"
| "json"
| "markdown"
| "notebook"
| "python"
| "react"
| "typescript";
interface FileReferenceChipProps {
path: string;
display?: "name" | "path";
active?: boolean;
className?: string;
textClassName?: string;
testId?: string;
}
export function FileReferenceChip({
path,
display = "name",
active = false,
className,
textClassName,
testId = "inline-file-path",
}: FileReferenceChipProps) {
const { name } = splitFilePath(path);
const kind = fileKindForPath(path);
const displayText = display === "path" ? path.replace(/\\/g, "/") : name;
return (
{displayText}
{path}
);
}
export function isLikelyFilePath(value: string): boolean {
const raw = value.trim();
if (!raw || raw.includes("\n")) return false;
if (/^[a-z][a-z0-9+.-]*:\/\//i.test(raw)) return false;
if (!/[\\/]/.test(raw) && !/^(dockerfile|makefile|readme|package-lock\.json)$/i.test(raw)) {
return false;
}
const normalized = raw.replace(/\\/g, "/");
const name = normalized.split("/").filter(Boolean).pop() ?? normalized;
if (!name || name === "." || name === "..") return false;
if (/^(dockerfile|makefile|readme|package-lock\.json)$/i.test(name)) return true;
return /\.[a-z0-9][a-z0-9_-]{0,12}$/i.test(name);
}
function splitFilePath(path: string): { directory: string; name: string } {
const normalized = path.replace(/\\/g, "/");
const slash = normalized.lastIndexOf("/");
if (slash < 0) return { directory: "", name: path };
return {
directory: normalized.slice(0, slash + 1),
name: normalized.slice(slash + 1) || normalized,
};
}
function fileKindForPath(path: string): FileReferenceKind {
const normalized = path.toLowerCase();
const name = normalized.split(/[\\/]/).pop() ?? normalized;
const ext = name.includes(".") ? name.split(".").pop() ?? "" : "";
if (name === "dockerfile") {
return "default";
}
switch (ext) {
case "py":
case "pyi":
return "python";
case "jsx":
case "tsx":
return "react";
case "ts":
return "typescript";
case "html":
case "htm":
return "html";
case "css":
case "scss":
case "sass":
return "css";
case "json":
case "jsonl":
return "json";
case "md":
case "mdx":
return "markdown";
case "ipynb":
return "notebook";
default:
return "default";
}
}
function FileReferenceIcon({ kind }: { kind: FileReferenceKind }) {
if (kind === "react") {
return (
);
}
if (kind === "default") {
return (
);
}
const label = fileKindLabel(kind);
return (
{label}
);
}
function fileKindLabel(kind: FileReferenceKind): string {
switch (kind) {
case "css":
return "#";
case "html":
return "H";
case "json":
return "{}";
case "markdown":
return "M";
case "notebook":
return "N";
case "python":
return "PY";
case "typescript":
return "TS";
default:
return "";
}
}