mirror of
https://github.com/openclaw/clawhub.git
synced 2026-08-14 08:52:21 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d45cf3d578 | ||
|
|
464365d3f8 | ||
|
|
07a51ee4fd | ||
|
|
ca690fcbd4 | ||
|
|
2bb8d8d238 | ||
|
|
1e025ed057 |
@@ -1,6 +1,16 @@
|
||||
import type { ClawdisSkillMetadata } from 'clawhub-schema'
|
||||
import { formatInstallCommand, formatInstallLabel } from './skillDetailUtils'
|
||||
|
||||
const CAPABILITY_DISPLAY: Record<string, { icon: string; label: string }> = {
|
||||
shell: { icon: '>_', label: 'Shell commands' },
|
||||
filesystem: { icon: '\uD83D\uDCC2', label: 'File access' },
|
||||
network: { icon: '\uD83C\uDF10', label: 'Web search/fetch' },
|
||||
browser: { icon: '\uD83D\uDD0D', label: 'Browser control' },
|
||||
sessions: { icon: '\u26A1', label: 'Session orchestration' },
|
||||
messaging: { icon: '\u2709\uFE0F', label: 'Message sending' },
|
||||
scheduling: { icon: '\u23F0', label: 'Scheduling/cron' },
|
||||
}
|
||||
|
||||
type SkillInstallCardProps = {
|
||||
clawdis: ClawdisSkillMetadata | undefined
|
||||
osLabels: string[]
|
||||
@@ -12,6 +22,7 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
const envVars = clawdis?.envVars ?? []
|
||||
const dependencies = clawdis?.dependencies ?? []
|
||||
const links = clawdis?.links
|
||||
const hasCapabilities = Boolean(clawdis?.capabilities?.length)
|
||||
const hasRuntimeRequirements = Boolean(
|
||||
clawdis?.emoji ||
|
||||
osLabels.length ||
|
||||
@@ -19,18 +30,35 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
requirements?.anyBins?.length ||
|
||||
requirements?.env?.length ||
|
||||
requirements?.config?.length ||
|
||||
clawdis?.primaryEnv ||
|
||||
envVars.length,
|
||||
envVars.length ||
|
||||
clawdis?.primaryEnv,
|
||||
)
|
||||
const hasInstallSpecs = installSpecs.length > 0
|
||||
const hasDependencies = dependencies.length > 0
|
||||
const hasLinks = Boolean(links?.homepage || links?.repository || links?.documentation)
|
||||
|
||||
if (!hasRuntimeRequirements && !hasInstallSpecs && !hasDependencies && !hasLinks) return null
|
||||
if (!hasCapabilities && !hasRuntimeRequirements && !hasInstallSpecs && !hasDependencies && !hasLinks) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="skill-hero-content">
|
||||
<div className="skill-hero-panels">
|
||||
{hasCapabilities ? (
|
||||
<div className="skill-panel">
|
||||
<h3 className="section-title" style={{ fontSize: '1rem', margin: 0 }}>
|
||||
Capabilities
|
||||
</h3>
|
||||
<div className="skill-panel-body">
|
||||
{clawdis!.capabilities!.map((cap) => (
|
||||
<div key={cap} className="stat">
|
||||
<span>{CAPABILITY_DISPLAY[cap]?.icon ?? cap}</span>
|
||||
<span>{CAPABILITY_DISPLAY[cap]?.label ?? cap}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
{hasRuntimeRequirements ? (
|
||||
<div className="skill-panel">
|
||||
<h3 className="section-title" style={{ fontSize: '1rem', margin: 0 }}>
|
||||
@@ -79,7 +107,10 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
<strong>Environment variables</strong>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.25rem', marginTop: '0.25rem' }}>
|
||||
{envVars.map((env, index) => (
|
||||
<div key={`${env.name}-${index}`} style={{ display: 'flex', alignItems: 'baseline', gap: '0.5rem' }}>
|
||||
<div
|
||||
key={`${env.name}-${index}`}
|
||||
style={{ display: 'flex', alignItems: 'baseline', gap: '0.5rem' }}
|
||||
>
|
||||
<code style={{ fontSize: '0.85rem' }}>{env.name}</code>
|
||||
{env.required === false ? (
|
||||
<span style={{ color: 'var(--ink-soft)', fontSize: '0.75rem' }}>optional</span>
|
||||
@@ -87,7 +118,9 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
<span style={{ color: 'var(--ink-accent)', fontSize: '0.75rem' }}>required</span>
|
||||
) : null}
|
||||
{env.description ? (
|
||||
<span style={{ color: 'var(--ink-soft)', fontSize: '0.8rem' }}>— {env.description}</span>
|
||||
<span style={{ color: 'var(--ink-soft)', fontSize: '0.8rem' }}>
|
||||
— {env.description}
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
@@ -108,16 +141,21 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
<div>
|
||||
<strong>{dep.name}</strong>
|
||||
<span style={{ color: 'var(--ink-soft)', fontSize: '0.85rem', marginLeft: '0.5rem' }}>
|
||||
{dep.type}{dep.version ? ` ${dep.version}` : ''}
|
||||
{dep.type}
|
||||
{dep.version ? ` ${dep.version}` : ''}
|
||||
</span>
|
||||
{dep.url ? (
|
||||
<div style={{ fontSize: '0.8rem' }}>
|
||||
<a href={dep.url} target="_blank" rel="noopener noreferrer">{dep.url}</a>
|
||||
<a href={dep.url} target="_blank" rel="noopener noreferrer">
|
||||
{dep.url}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
{dep.repository && dep.repository !== dep.url ? (
|
||||
<div style={{ fontSize: '0.8rem' }}>
|
||||
<a href={dep.repository} target="_blank" rel="noopener noreferrer">Source</a>
|
||||
<a href={dep.repository} target="_blank" rel="noopener noreferrer">
|
||||
Source
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -160,19 +198,25 @@ export function SkillInstallCard({ clawdis, osLabels }: SkillInstallCardProps) {
|
||||
{links?.homepage ? (
|
||||
<div className="stat">
|
||||
<strong>Homepage</strong>
|
||||
<a href={links.homepage} target="_blank" rel="noopener noreferrer">{links.homepage}</a>
|
||||
<a href={links.homepage} target="_blank" rel="noopener noreferrer">
|
||||
{links.homepage}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
{links?.repository ? (
|
||||
<div className="stat">
|
||||
<strong>Repository</strong>
|
||||
<a href={links.repository} target="_blank" rel="noopener noreferrer">{links.repository}</a>
|
||||
<a href={links.repository} target="_blank" rel="noopener noreferrer">
|
||||
{links.repository}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
{links?.documentation ? (
|
||||
<div className="stat">
|
||||
<strong>Docs</strong>
|
||||
<a href={links.documentation} target="_blank" rel="noopener noreferrer">{links.documentation}</a>
|
||||
<a href={links.documentation} target="_blank" rel="noopener noreferrer">
|
||||
{links.documentation}
|
||||
</a>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user