(res: http.ServerResponse, urlPath: string)
| 1098 | } |
| 1099 | |
| 1100 | private serveSkillDetail(res: http.ServerResponse, urlPath: string): void { |
| 1101 | const skillId = urlPath.replace("/api/skill/", ""); |
| 1102 | const skill = this.store.getSkill(skillId); |
| 1103 | if (!skill) { |
| 1104 | res.writeHead(404, { "Content-Type": "application/json" }); |
| 1105 | res.end(JSON.stringify({ error: "Skill not found" })); |
| 1106 | return; |
| 1107 | } |
| 1108 | |
| 1109 | const versions = this.store.getSkillVersions(skillId); |
| 1110 | const relatedTasks = this.store.getTasksBySkill(skillId); |
| 1111 | const files = fs.existsSync(skill.dirPath) ? this.walkDir(skill.dirPath, skill.dirPath) : []; |
| 1112 | |
| 1113 | const hubSkill = this.getHubSkillForLocal(skillId); |
| 1114 | |
| 1115 | this.jsonResponse(res, { |
| 1116 | skill: { ...skill, sharingVisibility: hubSkill?.visibility ?? null, sharingGroupId: hubSkill?.group_id ?? null }, |
| 1117 | versions: versions.map(v => ({ |
| 1118 | id: v.id, |
| 1119 | version: v.version, |
| 1120 | content: v.content, |
| 1121 | changelog: v.changelog, |
| 1122 | changeSummary: v.changeSummary, |
| 1123 | upgradeType: v.upgradeType, |
| 1124 | sourceTaskId: v.sourceTaskId, |
| 1125 | metrics: v.metrics, |
| 1126 | qualityScore: v.qualityScore, |
| 1127 | createdAt: v.createdAt, |
| 1128 | })), |
| 1129 | relatedTasks: relatedTasks.map(rt => ({ |
| 1130 | task: { |
| 1131 | id: rt.task.id, |
| 1132 | title: rt.task.title, |
| 1133 | status: rt.task.status, |
| 1134 | startedAt: rt.task.startedAt, |
| 1135 | }, |
| 1136 | relation: rt.relation, |
| 1137 | })), |
| 1138 | files, |
| 1139 | }); |
| 1140 | } |
| 1141 | |
| 1142 | private serveSkillFiles(res: http.ServerResponse, urlPath: string): void { |
| 1143 | const skillId = urlPath.replace("/api/skill/", "").replace("/files", ""); |
no test coverage detected