Add SClawHub security badge integration#185
Conversation
|
Someone is attempting to deploy a commit to the Amantus Machina Team on Vercel. A member of the Team first needs to authorize it. |
src/components/SClawHubBadge.tsx
Outdated
| useEffect(() => { | ||
| let cancelled = false | ||
| setLoading(true) | ||
| setError(false) | ||
|
|
||
| // Fetch security report from SClawHub API | ||
| fetch(`https://sclawhub.com/api/skills/${skillSlug}`) | ||
| .then((res) => { | ||
| if (!res.ok) { | ||
| throw new Error('Not scanned yet') |
There was a problem hiding this comment.
Badge never shows
fetch(...).then(res => { if (!res.ok) throw ... }) treats all non-2xx responses as errors and the component returns null when error is set, so if SClawHub returns anything other than 200 (e.g. a transient 500/timeout), the badge will permanently never render for that skill until a re-mount. If the intended behavior is “only hide on 404 (not scanned) but show on other errors once the API recovers”, don’t set a sticky error flag; instead distinguish 404 from retryable failures and allow subsequent renders to re-attempt (or just drop error state entirely and rely on report === null).
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/SClawHubBadge.tsx
Line: 34:43
Comment:
**Badge never shows**
`fetch(...).then(res => { if (!res.ok) throw ... })` treats *all* non-2xx responses as errors and the component returns `null` when `error` is set, so if SClawHub returns anything other than 200 (e.g. a transient 500/timeout), the badge will permanently never render for that skill until a re-mount. If the intended behavior is “only hide on 404 (not scanned) but show on other errors once the API recovers”, don’t set a sticky `error` flag; instead distinguish `404` from retryable failures and allow subsequent renders to re-attempt (or just drop `error` state entirely and rely on `report === null`).
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Thanks for catching this! You're absolutely right - the sticky error state would prevent recovery from transient failures.
Fixed in 75b11bc:
- Now only permanently hides on 404 (skill not scanned)
- Transient errors (500, timeout) allow retry on next render
- Removed the sticky
errorstate entirely
Badge will now gracefully handle temporary API issues. 🎉
src/components/SkillDetailPage.tsx
Outdated
| <div className="skill-actions"> | ||
| {/* SClawHub security badge - shows trust score if skill has been scanned */} | ||
| <div style={{ marginTop: '0.5rem' }}> | ||
| <SClawHubBadge skill={skill} ownerHandle={ownerHandle} variant="full" /> | ||
| </div> |
There was a problem hiding this comment.
Invalid JSX indentation
The new comment + <div> under .skill-actions is mis-indented relative to the surrounding JSX, which will trip the repo’s formatter/linting (Biome) and makes this block render harder to read. Please align it with the other children of <div className="skill-actions">.
| <div className="skill-actions"> | |
| {/* SClawHub security badge - shows trust score if skill has been scanned */} | |
| <div style={{ marginTop: '0.5rem' }}> | |
| <SClawHubBadge skill={skill} ownerHandle={ownerHandle} variant="full" /> | |
| </div> | |
| {/* SClawHub security badge - shows trust score if skill has been scanned */} | |
| <div style={{ marginTop: '0.5rem' }}> | |
| <SClawHubBadge skill={skill} ownerHandle={ownerHandle} variant="full" /> | |
| </div> |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/SkillDetailPage.tsx
Line: 530:534
Comment:
**Invalid JSX indentation**
The new comment + `<div>` under `.skill-actions` is mis-indented relative to the surrounding JSX, which will trip the repo’s formatter/linting (Biome) and makes this block render harder to read. Please align it with the other children of `<div className="skill-actions">`.
```suggestion
{/* SClawHub security badge - shows trust score if skill has been scanned */}
<div style={{ marginTop: '0.5rem' }}>
<SClawHubBadge skill={skill} ownerHandle={ownerHandle} variant="full" />
</div>
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Good catch! Fixed the indentation in 75b11bc to align with the other children of skill-actions.
Should pass Biome linting now. ✅
This PR adds optional security badges from SClawHub (https://sclawhub.com) to ClawHub skill pages. SClawHub is a community-driven, open-source security scanner for OpenClaw skills that provides: - Semgrep pattern matching for known vulnerabilities - Claude AI-powered security analysis - Trust scores (0-100) for quick assessment - Detailed security reports with remediation guidance - Displays trust score badge for scanned skills - Non-intrusive: only shows if skill has been scanned - Clickable: opens full report on sclawhub.com - Two variants: full (detailed) and compact (minimal) - Added SClawHub badge below existing skill badges - Shows full variant with score and view report link - Fully async: doesn't block page render - Graceful degradation: works if SClawHub is down - Comprehensive integration guide in docs/sclawhub-integration.md - Explains badge variants, trust scores, API endpoints - Developer guide for improving security scores - Opt-out instructions for privacy ✅ **Non-blocking** - Skills work without SClawHub scans ✅ **Open source** - Scanner code is public and auditable ✅ **Free forever** - No costs or subscriptions ✅ **Complementary** - Works alongside VirusTotal ✅ **Privacy-friendly** - No tracking or analytics ✅ **Developer-friendly** - Clear remediation guidance When viewing a skill that has been scanned: ``` 🛡️ Security: 95/100 → View Report ``` Clicking the badge opens the detailed report with: - Vulnerability findings - Severity classifications - Remediation recommendations - Code patterns detected While VirusTotal scans for malware signatures, SClawHub adds: - Context-aware code analysis via AI - Detection of obfuscation and evasion techniques - Understanding of OpenClaw-specific security patterns - Human-readable security explanations Together, they provide defense in depth for the OpenClaw ecosystem. - Endpoint: `GET https://sclawhub.com/api/skills/{owner}/{slug}` - Returns 404 if not scanned (badge doesn't render) - Async loading: no impact on page performance - No ClawHub infrastructure dependency Full scanner code: https://github.com/mladjan/Sclawhub - MIT Licensed - Community contributions welcome - Transparent scan methodology --- **Note:** SClawHub is an independent community project, not officially affiliated with ClawHub or OpenClaw. This integration is opt-in and non-intrusive.
- Badge was incorrectly placed inside the staffVisibilityTag ternary - Now correctly positioned after the ternary, before skill-actions - Fixes JSX compilation error
1. Improve error handling in SClawHubBadge: - Only permanently hide on 404 (skill not scanned) - Allow retries on transient errors (500, timeout) - Remove sticky error state to prevent permanent hiding 2. Fix JSX indentation in SkillDetailPage: - Align badge div with other skill-actions children - Matches Biome formatter requirements Addresses greptile-apps review comments
75b11bc to
02b1836
Compare
🛡️ Add SClawHub Security Badge Integration
This PR adds optional security badges from SClawHub to ClawHub skill pages, providing AI-powered security analysis alongside the existing VirusTotal integration.
📋 What is SClawHub?
SClawHub is a community-driven, open-source security scanner for OpenClaw skills that provides:
Live site: https://sclawhub.com
Source code: https://github.com/mladjan/Sclawhub (MIT Licensed)
🎯 Changes
New Component:
SClawHubBadge.tsxA React component that:
```tsx
<SClawHubBadge
skill={skill}
ownerHandle={ownerHandle}
variant="full" // or "compact"
/>
```
Integration:
SkillDetailPage.tsxDocumentation:
docs/sclawhub-integration.mdComprehensive guide covering:
🎨 Example
When viewing a skill that has been scanned on SClawHub:
```
🛡️ Security: 95/100 → View Report
```
Trust score colors:
Clicking the badge opens the detailed report with:
🔒 Why This Matters
Defense in Depth
AI-Powered Analysis
Community Transparency
⚡ Performance & Privacy
Performance
Privacy
API
🧪 Testing
Manual Testing
🔄 Future Enhancements
Planned Features
🤝 For Skill Developers
Getting Your Skill Scanned
Improving Your Score
📝 Documentation
Full integration guide: `docs/sclawhub-integration.md`
❓ FAQ
Q: Is this replacing VirusTotal?
A: No! SClawHub is complementary. VirusTotal scans for malware; SClawHub analyzes code patterns.
Q: What if my skill isn't scanned?
A: No badge appears. Skills work normally.
Q: Can I opt out?
A: Yes! Email kondormit@gmail.com with your skill slug.
Q: Who maintains SClawHub?
A: Independent community project by @kondormit. Not affiliated with OpenClaw/ClawHub.
Q: Is SClawHub open source?
A: Yes! MIT Licensed: https://github.com/mladjan/Sclawhub
🙏 Feedback Welcome
This is a community contribution to improve OpenClaw ecosystem security. Looking forward to your feedback!
Contact:
Note: SClawHub is an independent project and is not officially affiliated with ClawHub or OpenClaw. This integration is non-intrusive and opt-in for skill scanning.
Greptile Overview
Greptile Summary
This PR introduces an optional
SClawHubBadgeReact component that fetches a skill’s SClawHub security report (/api/skills/{owner}/{slug}) and, if present, renders a trust-score badge linking to the external report. The badge is integrated intoSkillDetailPageand new documentation was added underdocs/describing the API/UX and planned extensions.Confidence Score: 3/5
(2/5) Greptile learns from your feedback when you react with thumbs up/down!
Context used:
dashboard- AGENTS.md (source)