9380bd19e4
Co-authored-by: angiejones <jones.angie@gmail.com>
94 lines
3.0 KiB
TypeScript
94 lines
3.0 KiB
TypeScript
import type { Recipe } from "@site/src/components/recipe-card";
|
|
|
|
// Load all YAML files from your recipes folder
|
|
const recipeFiles = require.context(
|
|
"@site/src/pages/recipes/data/recipes",
|
|
false,
|
|
/\.ya?ml$/
|
|
);
|
|
|
|
export function getRecipeById(id: string): Recipe | null {
|
|
const allRecipes = loadAllRecipes();
|
|
return allRecipes.find((recipe) => recipe.id === id) || null;
|
|
}
|
|
|
|
export async function searchRecipes(query: string): Promise<Recipe[]> {
|
|
const allRecipes = loadAllRecipes();
|
|
|
|
if (!query) return allRecipes;
|
|
|
|
return allRecipes.filter((r) =>
|
|
r.title?.toLowerCase().includes(query.toLowerCase()) ||
|
|
r.description?.toLowerCase().includes(query.toLowerCase()) ||
|
|
r.action?.toLowerCase().includes(query.toLowerCase()) ||
|
|
r.activities?.some((a) => a.toLowerCase().includes(query.toLowerCase()))
|
|
);
|
|
}
|
|
|
|
function loadAllRecipes(): Recipe[] {
|
|
return recipeFiles.keys().map((key: string) => {
|
|
const parsed = recipeFiles(key).default || recipeFiles(key);
|
|
const id = key.replace(/^.*[\\/]/, "").replace(/\.(yaml|yml)$/, "");
|
|
return normalizeRecipe({ ...parsed, id });
|
|
});
|
|
}
|
|
|
|
function normalizeRecipe(recipe: any): Recipe {
|
|
const cleaned: Recipe = {
|
|
id: recipe.id || recipe.title?.toLowerCase().replace(/\s+/g, "-") || "untitled-recipe",
|
|
title: recipe.title || "Untitled Recipe",
|
|
description: recipe.description || "No description provided.",
|
|
instructions: recipe.instructions,
|
|
prompt: recipe.prompt,
|
|
extensions: Array.isArray(recipe.extensions)
|
|
? recipe.extensions.map((ext: any) =>
|
|
typeof ext === "string" ? { type: "builtin", name: ext } : ext
|
|
)
|
|
: [],
|
|
activities: Array.isArray(recipe.activities) ? recipe.activities : [],
|
|
version: recipe.version || "1.0.0",
|
|
author:
|
|
typeof recipe.author === "string"
|
|
? { contact: recipe.author }
|
|
: recipe.author || undefined,
|
|
action: recipe.action || undefined,
|
|
persona: recipe.persona || undefined,
|
|
tags: recipe.tags || [],
|
|
recipeUrl: "",
|
|
localPath: `documentation/src/pages/recipes/data/recipes/${recipe.id}.yaml`,
|
|
};
|
|
|
|
// Add parameters and populate missing required values
|
|
if (Array.isArray(recipe.parameters)) {
|
|
for (const param of recipe.parameters) {
|
|
if (param.requirement === "required" && !param.value) {
|
|
param.value = `{{${param.key}}}`;
|
|
}
|
|
}
|
|
(cleaned as any).parameters = recipe.parameters;
|
|
}
|
|
|
|
const configForGoose = {
|
|
title: cleaned.title,
|
|
description: cleaned.description,
|
|
instructions: cleaned.instructions,
|
|
prompt: cleaned.prompt,
|
|
activities: cleaned.activities,
|
|
extensions: cleaned.extensions,
|
|
parameters: (cleaned as any).parameters || []
|
|
};
|
|
|
|
const encoded = toBase64(JSON.stringify(configForGoose));
|
|
cleaned.recipeUrl = `goose://recipe?config=${encoded}`;
|
|
|
|
return cleaned;
|
|
}
|
|
|
|
|
|
function toBase64(str: string): string {
|
|
if (typeof window !== "undefined" && window.btoa) {
|
|
return window.btoa(unescape(encodeURIComponent(str)));
|
|
}
|
|
return Buffer.from(str).toString("base64");
|
|
}
|