chore(web): heroui skills
This commit is contained in:
148
.agents/skills/heroui-react/scripts/get_docs.mjs
Normal file
148
.agents/skills/heroui-react/scripts/get_docs.mjs
Normal file
@@ -0,0 +1,148 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Get non-component HeroUI documentation (guides, theming, releases).
|
||||
*
|
||||
* Usage:
|
||||
* node get_docs.mjs /docs/react/getting-started/theming
|
||||
* node get_docs.mjs /docs/react/releases/v3-0-0-beta-3
|
||||
*
|
||||
* Output:
|
||||
* MDX documentation content
|
||||
*
|
||||
* Note: For component docs, use get_component_docs.mjs instead.
|
||||
*/
|
||||
|
||||
const API_BASE = process.env.HEROUI_API_BASE || "https://mcp-api.heroui.com";
|
||||
const FALLBACK_BASE = "https://v3.heroui.com";
|
||||
const APP_PARAM = "app=react-skills";
|
||||
|
||||
/**
|
||||
* Fetch documentation from HeroUI API.
|
||||
* Uses v1 endpoint pattern: /v1/docs/:path
|
||||
*/
|
||||
async function fetchApi(path) {
|
||||
// The v1 API expects path without /docs/ prefix
|
||||
// Input: /docs/react/getting-started/theming
|
||||
// API expects: react/getting-started/theming (route is /v1/docs/:path(*))
|
||||
let apiPath = path.startsWith("/docs/")
|
||||
? path.slice(6) // Remove /docs/ prefix
|
||||
: path.startsWith("/")
|
||||
? path.slice(1) // Remove leading /
|
||||
: path;
|
||||
|
||||
const separator = "?";
|
||||
const url = `${API_BASE}/v1/docs/${apiPath}${separator}${APP_PARAM}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {"User-Agent": "HeroUI-Skill/1.0"},
|
||||
signal: AbortSignal.timeout(30000),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
console.error(`# API Error: HTTP ${response.status}`);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error(`# API Error: ${error.message}`);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch MDX directly from v3.heroui.com as fallback.
|
||||
*/
|
||||
async function fetchFallback(path) {
|
||||
// Ensure path starts with /docs and ends with .mdx
|
||||
let cleanPath = path.replace(/^\//, "");
|
||||
|
||||
if (!cleanPath.endsWith(".mdx")) {
|
||||
cleanPath = `${cleanPath}.mdx`;
|
||||
}
|
||||
|
||||
const url = `${FALLBACK_BASE}/${cleanPath}`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
headers: {"User-Agent": "HeroUI-Skill/1.0"},
|
||||
signal: AbortSignal.timeout(30000),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
return {error: `HTTP ${response.status}: ${response.statusText}`, path};
|
||||
}
|
||||
|
||||
const content = await response.text();
|
||||
|
||||
return {
|
||||
content,
|
||||
contentType: "mdx",
|
||||
path,
|
||||
source: "fallback",
|
||||
url,
|
||||
};
|
||||
} catch (error) {
|
||||
return {error: `Fetch Error: ${error.message}`, path};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function to get documentation for specified path.
|
||||
*/
|
||||
async function main() {
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
if (args.length === 0) {
|
||||
console.error("Usage: node get_docs.mjs <path>");
|
||||
console.error("Example: node get_docs.mjs /docs/react/getting-started/theming");
|
||||
console.error();
|
||||
console.error("Available paths include:");
|
||||
console.error(" /docs/react/getting-started/theming");
|
||||
console.error(" /docs/react/getting-started/colors");
|
||||
console.error(" /docs/react/getting-started/animations");
|
||||
console.error(" /docs/react/releases/v3-0-0-beta-3");
|
||||
console.error();
|
||||
console.error("Note: For component docs, use get_component_docs.mjs instead.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const path = args[0];
|
||||
|
||||
// Check if user is trying to get component docs
|
||||
if (path.includes("/components/")) {
|
||||
console.error("# Warning: Use get_component_docs.mjs for component documentation.");
|
||||
const componentName = path.split("/").pop().replace(".mdx", "");
|
||||
const titleCase = componentName.charAt(0).toUpperCase() + componentName.slice(1);
|
||||
|
||||
console.error(`# Example: node get_component_docs.mjs ${titleCase}`);
|
||||
}
|
||||
|
||||
console.error(`# Fetching documentation for ${path}...`);
|
||||
|
||||
// Try API first
|
||||
const data = await fetchApi(path);
|
||||
|
||||
if (data && data.content) {
|
||||
data.source = "api";
|
||||
console.log(data.content);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback to direct fetch
|
||||
console.error("# API failed, using fallback...");
|
||||
const fallbackData = await fetchFallback(path);
|
||||
|
||||
if (fallbackData.content) {
|
||||
console.log(fallbackData.content);
|
||||
} else {
|
||||
console.log(JSON.stringify(fallbackData, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user