✨ feat(api): ClawHub discover endpoint for skills marketplace#415
Merged
Conversation
Proxy the ClawHub registry so the skills Discover tab can show real marketplace data: browse mode wraps upstream /api/v1/skills?sort=downloads with cursor passthrough as next_page_token; q switches to /api/v1/search (no stats, no cursor upstream, so downloads/installs are omitted and next_page_token is null). No per-row detail enrichment — N+1 against the anonymous rate limit would 429. Refs #414
📊 Coverage ReportTotal coverage: 47.6% (generated files excluded) Per-package breakdown |
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
Replace the mock discover catalog with the real GET /api/clawhub/skills endpoint (debounced search, loading/error/empty states), and hide the installed-only filter row on the discover tab so it no longer shows a second, non-functional search box. Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
Add GET /api/clawhub/skills/{slug}, which resolves a skill's metadata and
downloads its archive to surface the README (SKILL.md) and file list.
Clicking a discover row now opens a URL-driven (?dslug=) detail sheet that
renders the rendered README, version, install count, author, and file
list, with an inline install button.
Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
- Strip YAML frontmatter from SKILL.md before preview so it no longer renders as a giant setext heading. - Richer list rows: skill glyph, author avatar/handle, 2-line summary clamp, hover chevron; skeleton loading and Empty states. - Detail sheet: identity header, meta chips (version/installs/author/ updated), collapsible file list, scrollable README, pinned install footer; widened to max-w-xl. Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
InstallToStore set only UserID for user-scope skills, leaving agent_id NULL. But a user skill lives within an agent's context (system → agent → user), so ListSkillsForAgentContext requires agent_id to match — the installed skill was filtered out of both the skills list and the agent runtime, so installs silently "did nothing". Set agent_id on install, matching CreateAgentSkill. Also translate the duplicate-name UNIQUE constraint on install into a 409 with a clear message instead of a generic 500. Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
- Install failures showed a generic toast: throwOnError rejects with the parsed error body, not an Error, so `instanceof Error` missed the message. Extract it via a shared apiErrorMessage helper. - Discover rows keyed "installed" off the ClawHub display name, which differs from the installed skill's frontmatter name (≈ slug), so an already-installed skill kept showing the Install button and 409'd on re-install. Match against the slug too. Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
…kills A ClawHub skill's slug can differ from its SKILL.md frontmatter name (the installed skill's name), so matching by name alone left already-installed skills showing an Install button. Record the install source (clawhub:<slug>) in skill metadata, expose it as Skill.source in the API, and match discover rows by source — falling back to name/slug for skills installed before this change. Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
Pull the skill pages back onto the design system instead of hand-rolled primitives and off-spec values: - Replace hand-built search inputs with InputGroup (was relative+absolute Search over a padded Input — a primitive CossUI already covers) - Snap all icons to the 16/20 grid (size-3/3.5/4.5 -> size-4/5) - Keep accent surgical: selected row uses bg-accent tint instead of a bg-primary/10 fill; scope badge demoted to secondary - Drop ALL-CAPS readme label and the arbitrary text-[8px] avatar size Refs #415
vaayne
added a commit
that referenced
this pull request
Jun 14, 2026
Redesign the skills page around a full-height two-pane workbench, with a card gallery for the marketplace — replacing the cramped 96px inspector and the single whole-page scroll. - Move Library/Discover toggle + Upload + Install into the app header (setHeaderActions), freeing the body for a full-height layout - Library: flat scope-grouped list (left) + full-height detail (right) with glyph/scope/status/invocation header, file count, source, and Overview/Files/Settings tabs; replaces the per-scope collapsibles - Discover: marketplace card grid; clicking a card opens the same full-height detail pane (right) on desktop, a Sheet on mobile, showing README + files + an Install-to scope toggle - Independent per-pane scroll: every flex column carries min-h-0 so the list and detail scroll on their own instead of one page-level scrollbar - Install surfaces specific API errors via apiErrorMessage Refs #415
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.
What
New
GET /api/clawhub/skillsendpoint — a read-only List over the ClawHub registry, feeding the skills Discover tab (#412 / #413) with real marketplace data.Why
The redesigned skills page ships its Discover tab on a mock catalog (
skill-mock-discover.ts, markedTODO(discover)). ClawHub already exposes everything needed; nothing in our API passed it through. The existingGET /api/skills/search(skills.sh via mcphub, used by the install dialog) is untouched.How
api-design.md(room forGET /api/clawhub/skills/{slug}later).q: proxy ClawHubGET /api/v1/skills?sort=downloads; upstreamnextCursorpasses through as opaquenext_page_token.qset: proxyGET /api/v1/search; upstream search has no stats and no cursor, sodownloads/installsare omitted andnext_page_tokenis null.slug, name, summary, version?, downloads?, installs?, updated_at (RFC3339), author_handle?, author_image?— browse mode has no owner upstream, search mode has no stats; all optional fields verified against the live API.api/spec/domain/clawhub/; handlerinternal/server/clawhub.gomirrorsSearchSkills(10s timeout, 502 on upstream failure); client logic ininternal/tools/skills/clawhub.goreuses the existingclawhubWithFallbackmirror/429 handling; exported viaBrowseCatalog.clawhub_test.gostubs upstream viaCLAWHUB_URL+httptest— browse stat/cursor mapping, search owner mapping, page-token passthrough, last page.listClawhubSkillsSDK call.Refs
Closes #414. Related: #412, #413.