{"openapi":"3.0.0","paths":{"/api/skills":{"get":{"description":"Paginated list of skills with sorting, filtering and full-text search. Pass \"q\" to search by slug, displayName and summary.","operationId":"SkillController_list","parameters":[{"name":"q","required":false,"in":"query","description":"Full-text search query. When provided, results are sorted by relevance by default.","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","description":"Page number","schema":{"minimum":1,"default":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Items per page","schema":{"minimum":1,"maximum":200,"default":25,"type":"number"}},{"name":"sort","required":false,"in":"query","description":"Sort field. \"relevance\" is only available when q is provided.","schema":{"default":"downloads","type":"string","enum":["downloads","stars","installs","updated","newest","name","relevance"]}},{"name":"dir","required":false,"in":"query","description":"Sort direction","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"name":"nonSuspiciousOnly","required":false,"in":"query","description":"Exclude suspicious/malicious skills","schema":{"default":false,"type":"boolean"}}],"responses":{"200":{"description":"Paginated skill list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillListResponseDto"}}}}},"summary":"Search skills","tags":["skills"]}},"/api/skills/{slug}":{"get":{"description":"Returns cached skill data and triggers background refresh from ClawHub. Includes security scans, files, moderation info.","operationId":"SkillController_getBySlug","parameters":[{"name":"slug","required":true,"in":"path","description":"Skill slug identifier","schema":{"example":"summarize","type":"string"}}],"responses":{"200":{"description":"Skill detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillDetailResponseDto"}}}},"404":{"description":"Skill not found"}},"summary":"Get skill by slug","tags":["skills"]}},"/api/skills/{slug}/comments":{"get":{"description":"Fetches comments from ClawHub in real-time. Returns user info and comment body.","operationId":"SkillController_getComments","parameters":[{"name":"slug","required":true,"in":"path","description":"Skill slug identifier","schema":{"example":"summarize","type":"string"}},{"name":"limit","required":false,"in":"query","description":"Max comments to return","schema":{"minimum":1,"maximum":200,"default":50,"type":"number"}}],"responses":{"200":{"description":"List of comments","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommentDto"}}}}},"404":{"description":"Skill not found"}},"summary":"Get skill comments","tags":["skills"]}},"/api/skills/{slug}/files":{"get":{"description":"Returns file content (e.g. SKILL.md). Cached with stale-while-revalidate.","operationId":"SkillController_getFile","parameters":[{"name":"slug","required":true,"in":"path","description":"Skill slug identifier","schema":{"example":"summarize","type":"string"}},{"name":"path","required":true,"in":"query","description":"File path within the skill","schema":{"example":"SKILL.md","type":"string"}}],"responses":{"200":{"description":"File content as plain text","content":{"application/json":{"schema":{"type":"string"}}}},"404":{"description":"Skill or file not found"}},"summary":"Get skill file content","tags":["skills"]}},"/health":{"get":{"description":"Returns service and database status","operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":"Service health","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["ok","degraded"],"example":"ok"},"timestamp":{"type":"string","format":"date-time"},"database":{"type":"string","enum":["connected","disconnected"],"example":"connected"}}}}}}},"summary":"Health check","tags":["health"]}}},"info":{"title":"ClawHub Layer API","description":"REST API cache layer for ClawHub skills data. Syncs skills from ClawHub Convex backend daily and serves them with stale-while-revalidate pattern.","version":"1.0.0","contact":{}},"tags":[{"name":"skills","description":"Browse, search and retrieve skill details"},{"name":"health","description":"Service health check"}],"servers":[],"components":{"schemas":{"SkillBadgesDto":{"type":"object","properties":{"highlighted":{"type":"boolean","description":"Highlighted / featured skill"},"official":{"type":"boolean","description":"Official skill"},"deprecated":{"type":"boolean","description":"Deprecated skill"}},"required":["highlighted","official","deprecated"]},"SkillStatsDto":{"type":"object","properties":{"downloads":{"type":"number"},"installsCurrent":{"type":"number"},"installsAllTime":{"type":"number"},"stars":{"type":"number"},"versions":{"type":"number"},"comments":{"type":"number"}},"required":["downloads","installsCurrent","installsAllTime","stars","versions","comments"]},"SkillVersionDto":{"type":"object","properties":{"version":{"type":"string","example":"1.0.2"},"createdAt":{"type":"number","description":"Unix ms timestamp"},"changelog":{"type":"string"},"changelogSource":{"type":"string","enum":["auto","user"]}},"required":["version","createdAt","changelog"]},"SkillOwnerDto":{"type":"object","properties":{"handle":{"type":"string","example":"steipete"},"displayName":{"type":"string","example":"Peter Steinberger"},"image":{"type":"string","description":"Avatar URL"},"kind":{"type":"string","enum":["user","org"]}},"required":["handle","displayName","image","kind"]},"SkillListItemDto":{"type":"object","properties":{"slug":{"type":"string","example":"summarize"},"displayName":{"type":"string","example":"Summarize"},"summary":{"type":"object"},"emoji":{"type":"object","description":"Skill emoji icon from metadata","example":"🧾"},"badges":{"$ref":"#/components/schemas/SkillBadgesDto"},"stats":{"$ref":"#/components/schemas/SkillStatsDto"},"tags":{"type":"object","description":"Version tags, e.g. { latest: \"1.0.0\" }","example":{"latest":"1.0.0"}},"createdAt":{"type":"number","description":"Unix ms"},"updatedAt":{"type":"number","description":"Unix ms"},"latestVersion":{"$ref":"#/components/schemas/SkillVersionDto"},"owner":{"$ref":"#/components/schemas/SkillOwnerDto"}},"required":["slug","displayName","badges","stats","tags","createdAt","updatedAt"]},"SkillListResponseDto":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/SkillListItemDto"}},"total":{"type":"number"},"page":{"type":"number"},"limit":{"type":"number"},"totalPages":{"type":"number"}},"required":["items","total","page","limit","totalPages"]},"SkillFileEntryDto":{"type":"object","properties":{"path":{"type":"string","example":"SKILL.md"},"size":{"type":"number","example":7910},"sha256":{"type":"string"},"contentType":{"type":"object","example":"text/markdown"}},"required":["path","size","sha256"]},"VtAnalysisDto":{"type":"object","properties":{"status":{"type":"string","example":"clean"},"verdict":{"type":"string","enum":["benign","suspicious","malicious"]},"analysis":{"type":"object"},"source":{"type":"object"},"checkedAt":{"type":"number","description":"Unix ms"}},"required":["status","verdict","checkedAt"]},"LlmDimensionDto":{"type":"object","properties":{"name":{"type":"string","example":"purpose_capability"},"label":{"type":"string","example":"Purpose & Capability"},"rating":{"type":"string","enum":["ok","note","warn"]},"detail":{"type":"string"}},"required":["name","label","rating","detail"]},"LlmAnalysisDto":{"type":"object","properties":{"status":{"type":"string","example":"clean"},"verdict":{"type":"string","enum":["benign","suspicious","malicious"]},"confidence":{"type":"string","enum":["high","medium","low"]},"summary":{"type":"object"},"guidance":{"type":"object"},"model":{"type":"string","example":"gpt-5-mini"},"checkedAt":{"type":"number","description":"Unix ms"},"dimensions":{"type":"array","items":{"$ref":"#/components/schemas/LlmDimensionDto"}}},"required":["status","verdict","confidence","model","checkedAt"]},"ModerationDto":{"type":"object","properties":{"isPendingScan":{"type":"boolean"},"isMalwareBlocked":{"type":"boolean"},"isSuspicious":{"type":"boolean"},"isHiddenByMod":{"type":"boolean"},"isRemoved":{"type":"boolean"},"verdict":{"type":"string","enum":["clean","suspicious","malicious"]},"reasonCodes":{"type":"array","items":{"type":"string"}},"summary":{"type":"object"}},"required":["isPendingScan","isMalwareBlocked","isSuspicious","isHiddenByMod","isRemoved","reasonCodes"]},"ForkOfDto":{"type":"object","properties":{"skillId":{"type":"string"},"kind":{"type":"string","enum":["fork","duplicate"]},"version":{"type":"object"},"at":{"type":"object","description":"Unix ms"}},"required":["skillId","kind"]},"SkillDetailResponseDto":{"type":"object","properties":{"slug":{"type":"string","example":"summarize"},"displayName":{"type":"string","example":"Summarize"},"summary":{"type":"object"},"emoji":{"type":"object","description":"Skill emoji icon from metadata","example":"🧾"},"badges":{"$ref":"#/components/schemas/SkillBadgesDto"},"stats":{"$ref":"#/components/schemas/SkillStatsDto"},"tags":{"type":"object","description":"Version tags, e.g. { latest: \"1.0.0\" }","example":{"latest":"1.0.0"}},"createdAt":{"type":"number","description":"Unix ms"},"updatedAt":{"type":"number","description":"Unix ms"},"latestVersion":{"$ref":"#/components/schemas/SkillVersionDto"},"owner":{"$ref":"#/components/schemas/SkillOwnerDto"},"sourceId":{"type":"string"},"license":{"type":"object","example":"MIT-0"},"platforms":{"example":["linux","darwin","win32"],"type":"array","items":{"type":"string"}},"files":{"type":"array","items":{"$ref":"#/components/schemas/SkillFileEntryDto"}},"vtAnalysis":{"$ref":"#/components/schemas/VtAnalysisDto"},"llmAnalysis":{"$ref":"#/components/schemas/LlmAnalysisDto"},"moderation":{"$ref":"#/components/schemas/ModerationDto"},"forkOf":{"$ref":"#/components/schemas/ForkOfDto"},"canonicalSkillId":{"type":"object"},"skillMd":{"type":"object","description":"SKILL.md content, auto-fetched from ClawHub"},"syncedAt":{"type":"string","description":"ISO timestamp of last bulk sync"},"detailSyncedAt":{"type":"object","description":"ISO timestamp of last detail enrichment"}},"required":["slug","displayName","badges","stats","tags","createdAt","updatedAt","sourceId","syncedAt"]},"CommentUserDto":{"type":"object","properties":{"handle":{"type":"string","example":"steipete"},"displayName":{"type":"string","example":"Peter Steinberger"},"image":{"type":"string","description":"Avatar URL"}},"required":["handle","displayName","image"]},"CommentDto":{"type":"object","properties":{"id":{"type":"string","description":"Comment ID"},"user":{"$ref":"#/components/schemas/CommentUserDto"},"body":{"type":"string","description":"Comment body text"},"createdAt":{"type":"number","description":"Unix ms timestamp"}},"required":["id","user","body","createdAt"]}}}}