feat: Skills.sh marketplace integration + navigation restructure

Skills.sh Marketplace:
- Add marketplace browser with search, detail panel, and install/uninstall
- Search API proxying skills.sh with lock file integration for installed state
- Install/remove APIs using `npx skills` CLI with SSE streaming progress
- SKILL.md content fetching via GitHub Git Trees API with in-memory caching
- MarketplaceSkillCard, MarketplaceSkillDetail, MarketplaceBrowser components
- InstallProgressDialog with real-time SSE log output
- SkillsManager gains "My Skills" / "Marketplace" segmented control
- Type definitions: MarketplaceSkill, SkillLockFile, SkillLockEntry

Navigation restructure:
- Split Extensions page into standalone /skills and /mcp top-level pages
- NavRail: replace single Extensions icon with separate Skills (ZapIcon) and MCP (Plug01Icon) entries
- /extensions page now redirects to /skills or /mcp based on ?tab param
- /plugins redirects updated to point to new routes
- Remove redundant source badges from SkillListItem (section headers suffice)

Other:
- Add WeChat user group QR code to README.md and README_CN.md
- i18n: add 19 marketplace-related keys in en.ts and zh.ts
- Bump version to 0.18.0

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
7418andClaude Opus 4.6 committed 2026-02-27 21:43:46 +08:00
1 parent 495319fe1f
commit c4d03c46e6
25 files changed
+1065 -83

No files matched your search

+27
View File
@@ -232,6 +232,33 @@ export interface SkillDefinition {
enabled: boolean;
}
// --- Marketplace (Skills.sh) ---
export interface MarketplaceSkill {
id: string;
skillId: string; // e.g. "git-commit"
name: string;
installs: number;
source: string; // e.g. "owner/repo"
isInstalled?: boolean;
installedAt?: string;
}
export interface SkillLockFile {
version: number;
skills: Record<string, SkillLockEntry>;
}
export interface SkillLockEntry {
source: string;
sourceType: string;
sourceUrl: string;
skillPath?: string;
skillFolderHash: string;
installedAt: string;
updatedAt: string;
}
export interface CreateSkillRequest {
name: string;
description: string;