import type { OpenClawHookMetadata, HookEntry, HookInstallSpec, HookInvocationPolicy, ParsedHookFrontmatter, } from "./types.js"; import { parseFrontmatterBlock } from "../markdown/frontmatter.js"; import { getFrontmatterString, normalizeStringList, parseFrontmatterBool, resolveOpenClawManifestBlock, resolveOpenClawManifestInstall, resolveOpenClawManifestOs, resolveOpenClawManifestRequires, } from "../shared/frontmatter.js"; export function parseFrontmatter(content: string): ParsedHookFrontmatter { return parseFrontmatterBlock(content); } function parseInstallSpec(input: unknown): HookInstallSpec | undefined { if (!input || typeof input !== "object") { return undefined; } const raw = input as Record; const kindRaw = typeof raw.kind === "string" ? raw.kind : typeof raw.type === "string" ? raw.type : ""; const kind = kindRaw.trim().toLowerCase(); if (kind !== "bundled" && kind !== "npm" && kind !== "git") { return undefined; } const spec: HookInstallSpec = { kind: kind, }; if (typeof raw.id === "string") { spec.id = raw.id; } if (typeof raw.label === "string") { spec.label = raw.label; } const bins = normalizeStringList(raw.bins); if (bins.length > 0) { spec.bins = bins; } if (typeof raw.package === "string") { spec.package = raw.package; } if (typeof raw.repository === "string") { spec.repository = raw.repository; } return spec; } export function resolveOpenClawMetadata( frontmatter: ParsedHookFrontmatter, ): OpenClawHookMetadata | undefined { const metadataObj = resolveOpenClawManifestBlock({ frontmatter }); if (!metadataObj) { return undefined; } const requires = resolveOpenClawManifestRequires(metadataObj); const install = resolveOpenClawManifestInstall(metadataObj, parseInstallSpec); const osRaw = resolveOpenClawManifestOs(metadataObj); const eventsRaw = normalizeStringList(metadataObj.events); return { always: typeof metadataObj.always === "boolean" ? metadataObj.always : undefined, emoji: typeof metadataObj.emoji === "string" ? metadataObj.emoji : undefined, homepage: typeof metadataObj.homepage === "string" ? metadataObj.homepage : undefined, hookKey: typeof metadataObj.hookKey === "string" ? metadataObj.hookKey : undefined, export: typeof metadataObj.export === "string" ? metadataObj.export : undefined, os: osRaw.length > 0 ? osRaw : undefined, events: eventsRaw.length > 0 ? eventsRaw : [], requires: requires, install: install.length > 0 ? install : undefined, }; } export function resolveHookInvocationPolicy( frontmatter: ParsedHookFrontmatter, ): HookInvocationPolicy { return { enabled: parseFrontmatterBool(getFrontmatterString(frontmatter, "enabled"), true), }; } export function resolveHookKey(hookName: string, entry?: HookEntry): string { return entry?.metadata?.hookKey ?? hookName; }