This commit is contained in:
Your Name committed 2026-06-13 22:02:04 -04:00
1 parent 20f43bd58d
commit 1ac727f4e5
10 files changed
+306 -122

No files matched your search

+140
View File
@@ -260,6 +260,54 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
},
required: ["sectionId"]
}
},
{
name: "update_footer_content",
description: "Update the content and links of the 4 Footer Blocks (Brand, Explore, Collections, Newsletter)",
inputSchema: {
type: "object",
properties: {
brandDescription: { type: "string", description: "Text for Block 1 (Brand tagline)" },
socialLinks: {
type: "object",
description: "URLs for facebook, instagram, tiktok (e.g. { facebookUrl: '...' })",
properties: {
facebookUrl: { type: "string" },
instagramUrl: { type: "string" },
tiktokUrl: { type: "string" }
}
},
exploreLinks: {
type: "array",
description: "Array of { label, url, order } for Block 2 (Explore)",
items: {
type: "object",
properties: { label: { type: "string" }, url: { type: "string" }, order: { type: "number" } }
}
},
collectionLinks: {
type: "array",
description: "Array of { label, url, order } for Block 3 (Collections)",
items: {
type: "object",
properties: { label: { type: "string" }, url: { type: "string" }, order: { type: "number" } }
}
},
supportLinks: {
type: "array",
description: "Array of { label, url, order } for Block 4 (Support/Legal)",
items: {
type: "object",
properties: { label: { type: "string" }, url: { type: "string" }, order: { type: "number" } }
}
}
}
}
},
{
name: "audit_missing_pages",
description: "Audit all menus and find links that do not have a corresponding dynamic page or hardcoded route",
inputSchema: { type: "object", properties: {} }
}
],
};
@@ -421,6 +469,98 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
const res = await api.delete(`/pages/sections/${params.sectionId}`);
return { content: [{ type: "text", text: JSON.stringify(res.data, null, 2) }] };
}
case "update_footer_content": {
const results = [];
if (params.brandDescription !== undefined || params.socialLinks) {
const settingsPayload: any = {};
if (params.brandDescription !== undefined) settingsPayload.footerDescription = params.brandDescription;
if (params.socialLinks?.facebookUrl !== undefined) settingsPayload.facebookUrl = params.socialLinks.facebookUrl;
if (params.socialLinks?.instagramUrl !== undefined) settingsPayload.instagramUrl = params.socialLinks.instagramUrl;
if (params.socialLinks?.tiktokUrl !== undefined) settingsPayload.tiktokUrl = params.socialLinks.tiktokUrl;
if (Object.keys(settingsPayload).length > 0) {
// First fetch existing settings because the backend requires full payload validation
const currentSettingsRes = await api.get("/settings");
const currentSettings = currentSettingsRes.data || {};
const mergedSettings = { ...currentSettings, ...settingsPayload };
// Remove null values so Elysia validation doesn't fail on t.Optional(t.String())
for (const key in mergedSettings) {
if (mergedSettings[key] === null) {
delete mergedSettings[key];
}
}
await api.put("/settings", mergedSettings);
results.push({ type: "settings", status: "success" });
}
}
if (params.exploreLinks) {
await api.put("/menus/footer-explore", { items: params.exploreLinks });
results.push({ type: "explore_links", status: "success" });
}
if (params.collectionLinks) {
await api.put("/menus/footer-collections", { items: params.collectionLinks });
results.push({ type: "collection_links", status: "success" });
}
if (params.supportLinks) {
await api.put("/menus/footer-support", { items: params.supportLinks });
results.push({ type: "support_links", status: "success" });
}
return { content: [{ type: "text", text: JSON.stringify(results, null, 2) }] };
}
case "audit_missing_pages": {
// 1. Fetch all menus
const menusRes = await api.get("/menus");
const menus = menusRes.data || [];
// 2. Fetch all dynamic pages
const pagesRes = await api.get("/pages");
const pages = pagesRes.data || [];
const createdSlugs = pages.map((p: any) => `/${p.slug}`);
// 3. Known SPA Hardcoded Routes
const hardcodedRoutes = [
"/", "/shop", "/login", "/cart", "/checkout", "/account", "/search", "/contact"
];
const missingLinks: any[] = [];
// 4. Audit
menus.forEach((menu: any) => {
if (menu.items && Array.isArray(menu.items)) {
menu.items.forEach((item: any) => {
const url = item.url;
if (!url) return;
// Skip external links
if (url.startsWith("http") || url.startsWith("mailto:") || url.startsWith("tel:")) return;
// Skip SPA Hardcoded routes
if (hardcodedRoutes.includes(url)) return;
// Skip dynamic collection routes natively handled by SPA (e.g. /collections/...)
if (url.startsWith("/collections/")) return;
// Check if it exists in created dynamic pages
if (!createdSlugs.includes(url)) {
missingLinks.push({
menuName: menu.name,
label: item.label,
url: url,
suggestedSlug: url.startsWith("/") ? url.substring(1) : url
});
}
});
}
});
return { content: [{ type: "text", text: JSON.stringify({ missingPages: missingLinks }, null, 2) }] };
}
default:
throw new Error(`Unknown tool: ${request.params.name}`);
}