Files
clawhub/convex/lib/skillPresentationBackfill.ts
T
Patrick Erichsen fd610627e0 feat: ingest and render skill presentation metadata (#3261)
* feat: ingest skill presentation metadata

* feat: render skill icons and clean titles

* feat: add skill presentation backfill

* fix: preserve hosted icons during backfill

* docs: clarify backfill icon ownership

* fix: track skill presentation provenance
2026-07-24 18:36:28 -05:00

56 lines
2.0 KiB
TypeScript

import type { Doc } from "../_generated/dataModel";
import {
isHostedSkillPresentationIconPath,
resolveSkillPresentation,
stripPresentationEmoji,
type OpenAiSkillPresentation,
} from "./skillPresentation";
import { getFrontmatterMetadata, getFrontmatterValue } from "./skills";
export function resolveHistoricalSkillPresentation(args: {
slug: string;
currentDisplayName: string;
currentSummary?: string;
frontmatter: Doc<"skillVersions">["parsed"]["frontmatter"];
openAi: OpenAiSkillPresentation;
}) {
const skillDisplayName = getFrontmatterValue(args.frontmatter, "name")?.trim();
const defaultDisplayName = resolveSkillPresentation({ slug: args.slug }).displayName;
const publisherDisplayName = [skillDisplayName, defaultDisplayName].some(
(candidate) =>
candidate &&
stripPresentationEmoji(candidate) === stripPresentationEmoji(args.currentDisplayName),
)
? undefined
: args.currentDisplayName;
const frontmatterMetadata = getFrontmatterMetadata(args.frontmatter);
const nestedDescription =
frontmatterMetadata &&
typeof frontmatterMetadata === "object" &&
!Array.isArray(frontmatterMetadata) &&
typeof (frontmatterMetadata as Record<string, unknown>).description === "string"
? ((frontmatterMetadata as Record<string, unknown>).description as string).trim()
: undefined;
const frontmatterDescription =
nestedDescription || getFrontmatterValue(args.frontmatter, "description")?.trim();
const currentSummary = args.currentSummary?.trim();
const publisherSummary =
currentSummary && currentSummary !== frontmatterDescription ? currentSummary : undefined;
return resolveSkillPresentation({
publisherDisplayName,
publisherSummary,
openAi: args.openAi,
skillDisplayName,
skillDescription: frontmatterDescription,
slug: args.slug,
});
}
export function preserveHistoricalHostedIcon(
...icons: Array<string | null | undefined>
): string | undefined {
return icons.find((icon): icon is string => isHostedSkillPresentationIconPath(icon));
}