help
npx skills add https://github.com/charlieclark/skill-help --skill help
Agent 安装分布
Skill 文档
/help
Manage help documentation for any project. Initialize a help center structure, generate articles from your codebase, import from an existing help site, set up a dashboard, and preview it locally.
Capabilities
| Action | What it does | Signal keywords |
|---|---|---|
| Init | Scaffold help config, directories, and template articles | “init help”, “set up help”, “help docs” |
| Generate | AI-generate help articles by analyzing the codebase | “generate docs”, “create articles”, “write help” |
| Update | Refresh existing articles from code changes | “update docs”, “refresh articles”, “regenerate” |
| Import | Crawl a public help center URL and convert to markdown | “import help”, “crawl docs”, “migrate help center” |
| Dashboard | Set up the help center dashboard (standalone or embedded) | “help dashboard”, “set up dashboard”, “help UI” |
| Preview | Launch the help dashboard locally for preview | “preview help”, “view docs”, “open help center” |
Routing Logic
1. Explicit intent (first match wins)
| User says | Action |
|---|---|
| “init help”, “set up help docs”, “help init” | Init |
| “generate docs”, “create help articles” | Generate |
| “update docs”, “refresh help articles” | Update |
| “import help center”, “crawl docs from URL” | Import |
| “set up help dashboard”, “help dashboard” | Dashboard |
| “preview help”, “open help center”, “view docs” | Preview |
2. Project-state fallback
| Project state | Default action |
|---|---|
No help.config.json |
Init |
| Config exists but no articles | Generate |
| Articles exist but no dashboard | Dashboard |
| Everything exists | Ask user |
Init
Create help documentation infrastructure.
Steps
- Check if
help.config.jsonexists in the working directory. If it does, show the user the current config and ask before overwriting. - Ask the user for their project name.
- Read the template config from
{{SKILL_DIR}}/templates/help.config.json. - Replace
{{PROJECT_NAME}}with the user’s chosen name. - Write the resulting config to
help.config.jsonin the working directory. - Create an
articles/directory with category subdirectories (e.g.,articles/getting-started/,articles/guides/,articles/faq/). - Copy template articles from
{{SKILL_DIR}}/templates/articles/into the matching subdirectories. - Confirm success and show the resulting directory structure.
Output
Created help.config.json
Created articles/
getting-started/
welcome.md
guides/
faq/
Run /help generate to create articles from your codebase.
Generate
AI-generate help articles by analyzing the codebase.
Steps
- Verify
help.config.jsonexists. If not, suggest running/help initfirst. - Read the config to get the project name, categories, and
articlesDir. - Scan the codebase for documentation-worthy sources:
- README files and existing docs
- API routes and endpoint handlers
- Component directories and their props/interfaces
- Config files and environment variables
- Error handling patterns and error codes
- Present the discovered areas to the user. Ask which to document, or suggest a default set based on the scan.
- For each chosen area, generate a markdown article with proper frontmatter:
--- title: "Article Title" slug: "article-title" category: "getting-started" description: "Short description for search and SEO." visibility: public lastUpdated: "YYYY-MM-DD" --- - Write articles to the appropriate category directories under
articlesDir. - If new categories were created, update
help.config.jsonto include them. - Show a summary of all generated articles with their paths.
Update
Update existing articles or regenerate from code changes.
Steps
- Read
help.config.jsonand list all current articles with theirlastUpdateddates. - Ask the user what to update:
- A specific article (by title or path)
- All articles in a category
- Full regeneration of everything
- Specific article:
- Read the article’s current content.
- Identify the relevant source code it documents.
- Rewrite the content while preserving the frontmatter structure (slug, category, visibility).
- Update the
lastUpdatedfield.
- Category or all:
- Scan for source code changes since each article’s
lastUpdateddate. - Regenerate only the articles whose underlying code has changed.
- Update
lastUpdatedon every modified article.
- Scan for source code changes since each article’s
- Show a diff summary: articles updated, articles unchanged, new articles suggested.
Import
Crawl a public help center URL and convert pages to markdown.
Steps
- Ask the user for the help center base URL.
- Attempt to find
sitemap.xmlat the URL (try/sitemap.xmland/help/sitemap.xml). - If no sitemap is found, crawl the main page and extract article links from navigation and content areas.
- For each discovered page:
- Fetch the HTML content.
- Extract the article body (strip nav, footer, sidebar chrome).
- Convert to clean markdown.
- Generate frontmatter from page metadata:
--- title: "Page Title" slug: "derived-from-url" category: "from-nav-structure" description: "From meta description tag" visibility: public lastUpdated: "YYYY-MM-DD" sourceUrl: "https://original-url" ---
- Organize articles into categories based on the source site’s navigation structure.
- Write all articles to the
articles/directory. - Update
help.config.jsonwith all discovered categories. - Show summary: number of articles imported, categories created, any pages that failed.
Notes
- Only public, unauthenticated pages can be imported.
- Rate-limit requests to avoid overloading the source server.
- If the source site blocks crawling, inform the user and suggest manual copy-paste.
Dashboard
Set up the help center dashboard.
Steps
-
Ask the user to choose:
- Standalone app — runs as a separate Vite app on port 3333
- Integrated into existing product — embeds help pages into the user’s framework
-
Standalone:
- Explain that it runs as a separate Vite app on port 3333, reading articles from the working directory.
- Check that
{{SKILL_DIR}}has dependencies installed. If not, runnpm install --prefix {{SKILL_DIR}}. - Launch with:
HELP_PROJECT_DIR="$(pwd)" npm run dev --prefix {{SKILL_DIR}} - Tell the user the dashboard is available at
http://localhost:3333.
-
Integrated:
-
Detect the user’s framework using
{{SKILL_DIR}}/utils/projectDetector.tslogic (checkpackage.jsonfor framework dependencies and inspect the project structure). -
Scaffold framework-specific routes and components:
Framework What to scaffold Next.js App Router /app/help/layout.tsx,/app/help/page.tsx,/app/help/[slug]/page.tsxNext.js Pages Router /pages/help/index.tsx,/pages/help/[slug].tsxExpress + React Router Express routes for API + static images; React Router routes for /helpand/help/:slugReact + Vite Help route component with client-side routing Astro /src/pages/help/index.astro,/src/pages/help/[slug].astroUnknown Fall back to standalone app -
Copy relevant components from
{{SKILL_DIR}}/components/into the user’s project (e.g.,HelpProvider.tsx,HelpArticle.tsx,HelpSidebar.tsx). -
Copy hooks from
{{SKILL_DIR}}/hooks/into the user’s project (e.g.,useHelp.ts,useHelpSearch.ts). -
Install required dependencies:
react-markdown. -
Images: Copy any
images/directory from the articles folder into the framework’s public static directory:Framework Copy images to Set imageBasePathtoNext.js (App/Pages) public/help/images//help/imagesExpress + React Router public/help/images//help/imagesReact + Vite public/help/images//help/imagesAstro public/help/images//help/images -
Pass
imageBasePathto<HelpArticle>and<HelpSidebar>components so relative image paths in articles resolve correctly.
-
Express + React Router Details
When the detected framework is express-react, scaffold the following:
1. Express API routes â routes/help.ts (or src/routes/help.ts)
import { Router } from 'express';
import fs from 'fs';
import path from 'path';
const router = Router();
function readConfig() {
return JSON.parse(fs.readFileSync(path.resolve('help.config.json'), 'utf-8'));
}
function collectMd(dir: string): string[] {
if (!fs.existsSync(dir)) return [];
const results: string[] = [];
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
const full = path.join(dir, entry.name);
if (entry.isDirectory()) results.push(...collectMd(full));
else if (entry.name.endsWith('.md')) results.push(full);
}
return results;
}
function parseFrontmatter(raw: string) {
const m = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
if (!m) return { data: {} as Record<string,string>, content: raw };
const data: Record<string,string> = {};
for (const line of m[1].split('\n')) {
const i = line.indexOf(':');
if (i > -1) data[line.slice(0,i).trim()] = line.slice(i+1).trim().replace(/^"|"$/g,'');
}
return { data, content: m[2] };
}
function getArticles() {
const config = readConfig();
const dir = path.resolve(config.settings.articlesDir);
return collectMd(dir).map(f => {
const { data, content } = parseFrontmatter(fs.readFileSync(f,'utf-8'));
return { ...data, slug: data.slug || path.basename(f,'.md'), content };
});
}
// GET /api/help/config
router.get('/config', (_req, res) => {
res.json(readConfig());
});
// GET /api/help/articles
router.get('/articles', (_req, res) => {
res.json(getArticles().map(({ content: _, ...rest }) => rest));
});
// GET /api/help/articles/:slug
router.get('/articles/:slug', (req, res) => {
const article = getArticles().find(a => a.slug === req.params.slug);
if (!article) return res.status(404).json({ error: 'Not found' });
res.json(article);
});
// GET /api/help/search?q=term
router.get('/search', (req, res) => {
const q = String(req.query.q || '').toLowerCase();
if (!q) return res.json([]);
const results = getArticles().filter(a =>
[a.title,a.summary,a.content,...(a.tags||[])].join(' ').toLowerCase().includes(q)
);
res.json(results.map(({ content: _, ...rest }) => rest));
});
export default router;
Tell the user to mount this in their Express app:
import helpRoutes from './routes/help';
app.use('/api/help', helpRoutes);
Also add static image serving:
import express from 'express';
app.use('/help/images', express.static('public/help/images'));
2. React Router routes â pages/HelpPage.tsx (or src/pages/HelpPage.tsx)
import { Routes, Route } from 'react-router-dom';
import { HelpProvider } from '../components/HelpProvider';
import { HelpCenter } from '../components/HelpCenter';
import { HelpArticlePage } from '../components/HelpArticlePage';
export default function HelpPage() {
return (
<HelpProvider config={config} articles={articles}>
<Routes>
<Route index element={<HelpCenter />} />
<Route path=":slug" element={<HelpArticlePage />} />
</Routes>
</HelpProvider>
);
}
Also scaffold two page-level components that the routes render:
HelpCenter.tsxâ Lists all articles grouped by category with search. UsesuseHelp()anduseHelpSearch()from the scaffolded hooks. UsesuseNavigate()from React Router to navigate to/help/:slug.HelpArticlePage.tsxâ ReadsslugfromuseParams(), fetches the article from/api/help/articles/:slug, and renders it with<HelpArticle imageBasePath="/help/images" />. Includes a back link to/help.
Tell the user to add the route to their router:
import HelpPage from './pages/HelpPage';
// In your <Routes>:
<Route path="/help/*" element={<HelpPage />} />
- Confirm the setup and show usage instructions.
Preview
Launch the help dashboard for local preview.
Steps
- Verify
help.config.jsonexists in the working directory. If not, suggest running/help init. - Check if
{{SKILL_DIR}}hasnode_modules/. If not, run:npm install --prefix {{SKILL_DIR}} - Start the Vite dev server:
HELP_PROJECT_DIR="$(pwd)" npm run dev --prefix {{SKILL_DIR}} - Run the server in the background so the user can continue working.
- Tell the user:
- Dashboard is available at http://localhost:3333
- Articles are live-reloaded on save
- Press Ctrl+C or kill the background process to stop
Template Location
All templates live in {{SKILL_DIR}}/templates/:
templates/
help.config.json # Project config template
articles/
getting-started/
welcome.md # Default welcome article
guides/
faq/
Troubleshooting
| Problem | Solution |
|---|---|
| “Cannot find help.config.json” | Run /help init to create the config file. |
| “No articles found” | Check that articlesDir in help.config.json points to the correct directory. |
| “Port 3333 in use” | Kill the existing process on port 3333, or set the PORT environment variable to override. |
| “Import found no articles” | Verify the URL is a public help center with accessible content (not behind authentication). |
| “Dashboard shows empty” | Ensure articles have visibility: public in their frontmatter. |