- {!left || !right ? (
-
Select two versions to compare.
- ) : left.id === right.id ? (
+ {!right ? (
+
Select a version to compare.
+ ) : left?.id === right.id ? (
Both sides are the same version.
) : (
@@ -2529,6 +2545,7 @@ function SkillVersionDiffDialog({
export function SkillDetailPage({
detail,
+ catalogSource,
routeSkills,
loading,
activeTab,
@@ -2567,6 +2584,7 @@ export function SkillDetailPage({
deletePending,
}: {
detail: CompanySkillDetail | null | undefined;
+ catalogSource?: CatalogSkillSource | null;
routeSkills?: CompanySkillRouteSubject[];
loading: boolean;
activeTab: SkillDetailTab;
@@ -2623,6 +2641,13 @@ export function SkillDetailPage({
const [leftVersionId, setLeftVersionId] = useState(null);
const [rightVersionId, setRightVersionId] = useState(null);
+ function openVersionDiff(targetVersionId?: string | null) {
+ const selection = getSkillVersionDiffSelection(sortedVersions, targetVersionId);
+ setLeftVersionId(selection.leftVersionId);
+ setRightVersionId(selection.rightVersionId);
+ setDiffOpen(Boolean(selection.rightVersionId));
+ }
+
// Track unsaved edits so we can float a save bar and warn before the page is
// unloaded with a dirty draft (PAP-10907 J).
const savedFileContent = file?.content ?? "";
@@ -2654,9 +2679,27 @@ export function SkillDetailPage({
// Look up the richer agent record (icon, paused) for agents using this skill.
const attachAgentMetaById = new Map(attachAgents.map((agent) => [agent.id, agent]));
- // Sidebar provenance: where this skill came from (org / path), linked when the
- // locator resolves to a URL (PAP-10907).
+ // Sidebar provenance: prefer the rich upstream attribution from the catalog
+ // entry (GitHub owner/repo/path with a real link). Catalog-installed skills
+ // only persist a local staging path, so without this they'd show a long,
+ // unhelpful filesystem path (PAP-10907).
+ const githubSource = catalogSource && catalogSource.type === "github" ? catalogSource : null;
+ const githubLabel = githubSource
+ ? githubSource.hostname === "github.com"
+ ? "GitHub"
+ : githubSource.hostname
+ : null;
+ const githubRepoText = githubSource
+ ? `${githubSource.owner}/${githubSource.repo}${githubSource.path ? `/${githubSource.path}` : ""}`
+ : null;
+ const githubHref = githubSource
+ ? githubSource.url
+ ?? `https://${githubSource.hostname}/${githubSource.owner}/${githubSource.repo}/tree/${githubSource.ref}/${githubSource.path}`.replace(/\/$/, "")
+ : null;
+ // Fallback for non-catalog skills: the recorded locator/path, middle-truncated
+ // so long file paths stay readable in the narrow sidebar.
const sourceLocatorText = skill.sourcePath || skill.sourceLocator || null;
+ const sourceLocatorDisplay = sourceLocatorText ? middleTruncate(sourceLocatorText, 44) : null;
const sourceHref =
skill.homepageUrl
?? (sourceLocatorText && /^(https?:\/\/|[\w.-]+\.[a-z]{2,}\/)/i.test(sourceLocatorText)
@@ -2786,13 +2829,10 @@ export function SkillDetailPage({
{versionsLoading ? "Loading versions..." : `${versions.length} ${versions.length === 1 ? "version" : "versions"}`}