web: serve raw SKILL.md downloads instead of per-skill ZIPs#18
Merged
Conversation
Switch the per-skill download button on plugin pages to fetch the raw markdown file directly. The catalog generator now copies each SKILL.md to public/generated/downloads/skills/<name>.md instead of zipping it, the plugin page exposes a "Download" button pointing at that file, and the bulk panel bundles .md files inside the selected-skills archive. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR updates the web marketplace to download individual skills as raw SKILL.md markdown files (served as static assets) instead of generating and serving per-skill ZIP archives, while keeping the bulk-download-as-ZIP experience.
Changes:
- Switch per-skill downloads from
*.zipto*.mdand adjust UI copy/button labeling accordingly. - Update catalog generation to copy each
SKILL.mdintopublic/generated/downloads/skills/<name>.mdand pointskill.downloadUrlat the.md. - Update the bulk download panel to bundle selected skills as
*.mdentries (not nested ZIPs).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| web/src/components/skill-bulk-panel.tsx | Updates bulk ZIP entry names to *.md to match the new per-skill raw download format. |
| web/src/app/plugins/[slug]/page.tsx | Updates skills section copy and changes the per-skill button to download *.md with a download filename. |
| web/scripts/generate-catalog.mjs | Replaces per-skill ZIP generation with copying SKILL.md into the generated public downloads directory and updates downloadUrl. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
176
to
+182
| const raw = await readTextAbsolute(skillFile); | ||
| const parsed = matter(raw); | ||
| const description = readFrontmatterString(parsed.data.description, skillSlug); | ||
| const name = readFrontmatterString(parsed.data.name, skillSlug); | ||
| const downloadUrl = `/generated/downloads/skills/${name}.zip`; | ||
| const downloadUrl = `/generated/downloads/skills/${name}.md`; | ||
|
|
||
| await writeZip(path.join(downloadsDir, "skills", `${name}.zip`), [ | ||
| { source: skillDir, target: `plugins/${pluginSlug}/skills/${skillSlug}` }, | ||
| ]); | ||
| await fs.copyFile(skillFile, path.join(downloadsDir, "skills", `${name}.md`)); |
Comment on lines
30
to
34
| .filter((skill) => selectedSkills.has(skill.name)) | ||
| .map((skill) => ({ | ||
| name: `${skill.name}.zip`, | ||
| name: `${skill.name}.md`, | ||
| url: skill.downloadUrl, | ||
| })); |
Comment on lines
147
to
+152
| <a | ||
| href={skill.downloadUrl} | ||
| download | ||
| download={`${skill.name}.md`} | ||
| className="rounded-full border border-white/16 px-4 py-2 font-mono text-xs font-bold text-white transition hover:border-accent hover:text-accent" | ||
| > | ||
| ZIP | ||
| Download |
Komoszek
approved these changes
May 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/plugins/<slug>now downloads the rawSKILL.mddirectly instead of a one-file ZIP, withdownload=\"<name>.md\"so browsers save it with the skill name.web/scripts/generate-catalog.mjscopies eachSKILL.mdtopublic/generated/downloads/skills/<name>.md(no JSZip per skill) and the catalog'sskill.downloadUrlpoints at the.md.SkillBulkPanelkeeps the multi-select archive flow, but the inner entries are now<name>.mdfiles rather than nested.zips.SKILL.mdfile" /Downloadbutton).Test plan
cd web && npm run generate:catalogproducespublic/generated/downloads/skills/*.md(36 files) and no per-skill.zips./plugins/flutter-analytics: "Download" button on each skill card saves e.g.flutter-analytics-usage.mdwith valid frontmatter + body.<name>.mdentries.npx tsc --noEmitpasses inweb/.Made with Cursor