mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 03:17:28 +08:00
feat(webui): support --force install for suspicious skills
This commit is contained in:
@@ -916,7 +916,18 @@ func (s *RegistryServer) handleWebUISkills(w http.ResponseWriter, r *http.Reques
|
||||
http.Error(w, "clawhub is not installed. please install clawhub first.", http.StatusPreconditionFailed)
|
||||
return
|
||||
}
|
||||
cmd := exec.CommandContext(r.Context(), clawhubPath, "install", name)
|
||||
ignoreSuspicious := false
|
||||
switch v := body["ignore_suspicious"].(type) {
|
||||
case bool:
|
||||
ignoreSuspicious = v
|
||||
case string:
|
||||
ignoreSuspicious = strings.EqualFold(strings.TrimSpace(v), "true") || strings.TrimSpace(v) == "1"
|
||||
}
|
||||
args := []string{"install", name}
|
||||
if ignoreSuspicious {
|
||||
args = append(args, "--force")
|
||||
}
|
||||
cmd := exec.CommandContext(r.Context(), clawhubPath, args...)
|
||||
cmd.Dir = strings.TrimSpace(s.workspacePath)
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
|
||||
@@ -189,6 +189,7 @@ const resources = {
|
||||
skillsImportDoneMessage: 'Skill imported successfully.',
|
||||
skillsFileSaved: 'Skill file saved successfully.',
|
||||
skillsNamePlaceholder: 'skill name',
|
||||
skillsIgnoreSuspicious: 'Ignore suspicious warning (use --force)',
|
||||
skillsClawhubNotFound: 'clawhub not found',
|
||||
skillsClawhubStatus: 'clawhub',
|
||||
skillsAdd: 'Add Skill',
|
||||
@@ -491,6 +492,7 @@ const resources = {
|
||||
skillsImportDoneMessage: '技能导入成功。',
|
||||
skillsFileSaved: '技能文件保存成功。',
|
||||
skillsNamePlaceholder: '技能名',
|
||||
skillsIgnoreSuspicious: '忽略可疑告警(使用 --force)',
|
||||
skillsClawhubNotFound: '未找到 clawhub',
|
||||
skillsClawhubStatus: 'clawhub',
|
||||
skillsAdd: '添加技能',
|
||||
|
||||
@@ -11,6 +11,7 @@ const Skills: React.FC = () => {
|
||||
const ui = useUI();
|
||||
const [installName, setInstallName] = useState('');
|
||||
const [installingSkill, setInstallingSkill] = useState(false);
|
||||
const [ignoreSuspicious, setIgnoreSuspicious] = useState(false);
|
||||
const qp = (k: string, v: string) => `${q}${q ? '&' : '?'}${k}=${encodeURIComponent(v)}`;
|
||||
|
||||
const [isFileModalOpen, setIsFileModalOpen] = useState(false);
|
||||
@@ -76,7 +77,7 @@ const Skills: React.FC = () => {
|
||||
const r = await fetch(`/webui/api/skills${q}`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ action: 'install', name }),
|
||||
body: JSON.stringify({ action: 'install', name, ignore_suspicious: ignoreSuspicious }),
|
||||
});
|
||||
if (!r.ok) {
|
||||
ui.hideLoading();
|
||||
@@ -190,6 +191,15 @@ const Skills: React.FC = () => {
|
||||
<div className="flex items-center gap-2">
|
||||
<input disabled={installingSkill} value={installName} onChange={(e) => setInstallName(e.target.value)} placeholder={t('skillsNamePlaceholder')} className="px-3 py-2 bg-zinc-950 border border-zinc-800 rounded-lg text-sm disabled:opacity-60" />
|
||||
<button disabled={installingSkill} onClick={installSkill} className="px-3 py-2 bg-emerald-600 hover:bg-emerald-500 disabled:opacity-60 disabled:cursor-not-allowed text-white rounded-lg text-sm font-medium">{installingSkill ? t('loading') : t('install')}</button>
|
||||
<label className="flex items-center gap-2 text-xs text-zinc-400">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={ignoreSuspicious}
|
||||
disabled={installingSkill}
|
||||
onChange={(e) => setIgnoreSuspicious(e.target.checked)}
|
||||
/>
|
||||
{t('skillsIgnoreSuspicious')}
|
||||
</label>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`text-xs px-2 py-1 rounded-md border ${clawhubInstalled ? 'text-emerald-300 border-emerald-700/50 bg-emerald-900/20' : 'text-amber-300 border-amber-700/50 bg-amber-900/20'}`} title={clawhubPath || t('skillsClawhubNotFound')}>
|
||||
|
||||
Reference in New Issue
Block a user