"use client"; import { useState, useEffect, useCallback, useRef } from "react"; import { useIsMobile } from "@/hooks/useIsMobile"; import { useI18n } from "@/hooks/useI18n"; import type { SkillInfo as Skill, SkillInstallScope, SkillSearchResult, SkillsResponse, SkillUpdateResult, } from "@/lib/api-types"; function shortenPath(p: string): string { // Match common home dir patterns: /Users/xxx, /home/xxx return p.replace(/^\/(?:Users|home)\/[^/]+/, "~"); } function sourceLabel(skill: Skill): string { const src = skill.sourceInfo?.source; const scope = skill.sourceInfo?.scope; if (scope === "user" || src === "user") return "global"; if (scope === "project" || src === "project") return "project"; return "path"; } function skillGroupLabel(skill: Skill): string { const source = sourceLabel(skill); if (source === "path") return source; return skill.install?.skillsShUrl ? `${source} / skills.sh` : source; } function updateKey(skill: Skill): string | null { return skill.install ? `${skill.install.scope}\0${skill.install.package}` : null; } function shortVersion(version?: string): string { return version ? version.slice(0, 8) : "unknown"; } function Toggle({ enabled, loading, onToggle, }: { enabled: boolean; loading: boolean; onToggle: () => void; }) { const { t } = useI18n(); return ( ); } function SkillDetail({ skill, cwd, onToggle, toggling, saveError, updateStatus, checkingUpdate, updating, updateError, onCheckUpdate, onUpdate, }: { skill: Skill; cwd: string; onToggle: (skill: Skill) => void; toggling: boolean; saveError: string | null; updateStatus?: SkillUpdateResult; checkingUpdate: boolean; updating: boolean; updateError: string | null; onCheckUpdate: () => void; onUpdate: () => void; }) { const { t } = useI18n(); const label = sourceLabel(skill); const enabled = !skill.disableModelInvocation; function displayPath(p: string): string { if (label === "project" && p.startsWith(cwd)) { const rel = p.slice(cwd.length).replace(/^[/\\]/, ""); return `./${rel}`; } return shortenPath(p); } return (
{shortenPath(cwd)}