SkillsGetOrDeleteHandler 处理: - GET /v1/skills/{id} 获取单个 Skill 的所有版本信息 - DELETE /v1/skills/{id} 卸载 Skill (删除其所有目录) - GET /v1/skills/{id}/versions 列出指定 Skill 的所有版本 - POST /v1/skills/{id}/versions 创建/更新指定版本 - DELETE /v1/skills/{id}/versi
()
| 320 | // - POST /v1/skills/{id}/versions 创建/更新指定版本 |
| 321 | // - DELETE /v1/skills/{id}/versions/{version} 删除指定版本 |
| 322 | func (s *Server) SkillsGetOrDeleteHandler() http.Handler { |
| 323 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 324 | if s.skillsManager == nil { |
| 325 | http.Error(w, "skills manager not initialized", http.StatusServiceUnavailable) |
| 326 | return |
| 327 | } |
| 328 | |
| 329 | // 提取路径部分: /v1/skills/{...} |
| 330 | raw := strings.TrimPrefix(r.URL.Path, "/v1/skills/") |
| 331 | if raw == "" || raw == "/v1/skills" { |
| 332 | http.Error(w, "skill id is required", http.StatusBadRequest) |
| 333 | return |
| 334 | } |
| 335 | path := strings.Trim(raw, "/") |
| 336 | parts := strings.Split(path, "/") |
| 337 | |
| 338 | // 仅包含 id: /v1/skills/{id} |
| 339 | if len(parts) == 1 { |
| 340 | id := parts[0] |
| 341 | |
| 342 | switch r.Method { |
| 343 | case http.MethodGet: |
| 344 | ctx := r.Context() |
| 345 | all, err := s.skillsManager.List(ctx) |
| 346 | if err != nil { |
| 347 | http.Error(w, "list skills failed: "+err.Error(), http.StatusInternalServerError) |
| 348 | return |
| 349 | } |
| 350 | var filtered []skills.Info |
| 351 | for _, info := range all { |
| 352 | if info.ID == id { |
| 353 | filtered = append(filtered, info) |
| 354 | } |
| 355 | } |
| 356 | if len(filtered) == 0 { |
| 357 | http.Error(w, "skill not found", http.StatusNotFound) |
| 358 | return |
| 359 | } |
| 360 | writeJSON(w, http.StatusOK, filtered) |
| 361 | |
| 362 | case http.MethodDelete: |
| 363 | ctx := r.Context() |
| 364 | if err := s.skillsManager.Uninstall(ctx, id); err != nil { |
| 365 | http.Error(w, "uninstall skill failed: "+err.Error(), http.StatusInternalServerError) |
| 366 | return |
| 367 | } |
| 368 | w.WriteHeader(http.StatusNoContent) |
| 369 | |
| 370 | default: |
| 371 | http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
| 372 | } |
| 373 | return |
| 374 | } |
| 375 | |
| 376 | // /v1/skills/{id}/versions 或 /v1/skills/{id}/versions/{version} |
| 377 | if len(parts) >= 2 && parts[1] == "versions" { |
| 378 | id := parts[0] |
| 379 |
nothing calls this directly
no test coverage detected