feat: add .skill file preview support

Enable previewing .skill files (ZIP archives) by extracting and displaying
their SKILL.md content. Add caching to avoid repeated ZIP extraction.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hetaoBackend
2026-01-31 22:27:06 +08:00
parent 624f758163
commit f31258dd10
4 changed files with 79 additions and 2 deletions

View File

@@ -75,14 +75,21 @@ export function ArtifactFileDetail({
}
return filepathFromProps;
}, [filepathFromProps, isWriteFile]);
const isSkillFile = useMemo(() => {
return filepath.endsWith(".skill");
}, [filepath]);
const { isCodeFile, language } = useMemo(() => {
if (isWriteFile) {
let language = checkCodeFile(filepath).language;
language ??= "text";
return { isCodeFile: true, language };
}
// Treat .skill files as markdown (they contain SKILL.md)
if (isSkillFile) {
return { isCodeFile: true, language: "markdown" };
}
return checkCodeFile(filepath);
}, [filepath, isWriteFile]);
}, [filepath, isWriteFile, isSkillFile]);
const previewable = useMemo(() => {
return (language === "html" && !isWriteFile) || language === "markdown";
}, [isWriteFile, language]);

View File

@@ -30,6 +30,8 @@ export function useArtifactContent({
return loadArtifactContent({ filepath, threadId });
},
enabled,
// Cache artifact content for 5 minutes to avoid repeated fetches (especially for .skill ZIP extraction)
staleTime: 5 * 60 * 1000,
});
return { content: isWriteFile ? content : data, isLoading, error };
}

View File

@@ -13,7 +13,7 @@ export async function loadArtifactContent({
}) {
let enhancedFilepath = filepath;
if (filepath.endsWith(".skill")) {
enhancedFilepath = filepath.replace(".md", ".skill/SKILL.md");
enhancedFilepath = filepath + "/SKILL.md";
}
const url = urlOfArtifact({ filepath: enhancedFilepath, threadId });
const response = await fetch(url);