docmk 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -304,10 +304,13 @@ init_parser();
304
304
  import { createServer } from "vite";
305
305
  import vue from "@vitejs/plugin-vue";
306
306
  import path2 from "path";
307
+ import { fileURLToPath } from "url";
308
+ var __dirname = path2.dirname(fileURLToPath(import.meta.url));
309
+ var packageRoot = path2.resolve(__dirname, "../..");
307
310
  async function createViteDevServer(options) {
308
311
  let currentConfig = options.config;
309
312
  const server = await createServer({
310
- root: path2.resolve(process.cwd(), "src/client"),
313
+ root: path2.resolve(packageRoot, "src/client"),
311
314
  server: {
312
315
  port: options.port,
313
316
  host: "localhost"
@@ -356,7 +359,7 @@ async function createViteDevServer(options) {
356
359
  ],
357
360
  resolve: {
358
361
  alias: {
359
- "@": path2.resolve(process.cwd(), "src/client")
362
+ "@": path2.resolve(packageRoot, "src/client")
360
363
  }
361
364
  },
362
365
  define: {
@@ -433,7 +436,10 @@ import path5 from "path";
433
436
  import { build } from "vite";
434
437
  import vue2 from "@vitejs/plugin-vue";
435
438
  import path4 from "path";
439
+ import { fileURLToPath as fileURLToPath2 } from "url";
436
440
  import fs2 from "fs/promises";
441
+ var __dirname2 = path4.dirname(fileURLToPath2(import.meta.url));
442
+ var packageRoot2 = path4.resolve(__dirname2, "../..");
437
443
  async function buildSite(options, config) {
438
444
  console.log("\u{1F3D7}\uFE0F Building documentation site...");
439
445
  await fs2.mkdir(options.output, { recursive: true });
@@ -441,14 +447,14 @@ async function buildSite(options, config) {
441
447
  await fs2.writeFile(configPath, JSON.stringify(config, null, 2));
442
448
  try {
443
449
  await build({
444
- root: path4.resolve(process.cwd(), "src/client"),
450
+ root: path4.resolve(packageRoot2, "src/client"),
445
451
  base: config.siteConfig.baseUrl,
446
452
  build: {
447
453
  outDir: options.output,
448
454
  emptyOutDir: true,
449
455
  rollupOptions: {
450
456
  input: {
451
- main: path4.resolve(process.cwd(), "src/client/index.html")
457
+ main: path4.resolve(packageRoot2, "src/client/index.html")
452
458
  }
453
459
  }
454
460
  },
@@ -472,7 +478,7 @@ async function buildSite(options, config) {
472
478
  ],
473
479
  resolve: {
474
480
  alias: {
475
- "@": path4.resolve(process.cwd(), "src/client")
481
+ "@": path4.resolve(packageRoot2, "src/client")
476
482
  }
477
483
  },
478
484
  define: {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/scanner/index.ts","../src/parser/index.ts","../src/cli/index.ts","../src/cli/commands/dev.ts","../src/builder/vite-dev.ts","../src/cli/commands/build.ts","../src/builder/index.ts","../src/cli/commands/preview.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\nimport { SkillDirectory, SkillFile } from '../types/index.js'\n\nexport async function scanSkillsDirectory(sourceDir: string): Promise<SkillDirectory[]> {\n try {\n await fs.access(sourceDir)\n } catch {\n throw new Error(`Source directory not found: ${sourceDir}`)\n }\n\n const entries = await fs.readdir(sourceDir, { withFileTypes: true })\n const directories: SkillDirectory[] = []\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const dirPath = path.join(sourceDir, entry.name)\n const skillDirectory = await scanDirectory(dirPath, entry.name)\n directories.push(skillDirectory)\n }\n }\n\n return directories\n}\n\nasync function scanDirectory(dirPath: string, name: string): Promise<SkillDirectory> {\n const entries = await fs.readdir(dirPath, { withFileTypes: true })\n const children: (SkillDirectory | SkillFile)[] = []\n let skillFile: SkillFile | undefined\n\n for (const entry of entries) {\n const entryPath = path.join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n const subDir = await scanDirectory(entryPath, entry.name)\n children.push(subDir)\n } else if (entry.isFile() && entry.name.endsWith('.md')) {\n const file = await parseMarkdownFile(entryPath, entry.name)\n \n if (entry.name === 'SKILL.md') {\n skillFile = file\n } else {\n children.push(file)\n }\n }\n }\n\n return {\n path: dirPath,\n name,\n children,\n skillFile\n }\n}\n\nasync function parseMarkdownFile(filePath: string, fileName: string): Promise<SkillFile> {\n const content = await fs.readFile(filePath, 'utf-8')\n const stats = await fs.stat(filePath)\n\n // Basic frontmatter extraction\n const frontmatterMatch = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/)\n const frontmatter: Record<string, any> = {}\n let markdownContent = content\n\n if (frontmatterMatch) {\n // Remove frontmatter from content\n markdownContent = content.slice(frontmatterMatch[0].length)\n \n // Parse frontmatter key-value pairs\n const fmLines = frontmatterMatch[1].split(/\\r?\\n/)\n for (const line of fmLines) {\n const colonIndex = line.indexOf(':')\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim()\n const value = line.slice(colonIndex + 1).trim().replace(/^[\"']|[\"']$/g, '')\n if (key && value) {\n frontmatter[key] = value\n }\n }\n }\n }\n\n return {\n path: filePath,\n name: fileName,\n title: frontmatter.title || fileName.replace('.md', ''),\n description: frontmatter.description,\n content: markdownContent,\n frontmatter,\n lastModified: stats.mtime.getTime()\n }\n}\n\nexport async function watchSkillsDirectory(\n sourceDir: string, \n callback: (directories: SkillDirectory[]) => void\n) {\n const chokidar = await import('chokidar')\n \n const watcher = chokidar.watch(sourceDir, {\n ignored: /node_modules/,\n persistent: true,\n ignoreInitial: true\n })\n\n let debounceTimer: NodeJS.Timeout\n\n const handleChange = () => {\n clearTimeout(debounceTimer)\n debounceTimer = setTimeout(async () => {\n try {\n const directories = await scanSkillsDirectory(sourceDir)\n callback(directories)\n } catch (error) {\n console.error('Error rescanning source directory:', error)\n }\n }, 300)\n }\n\n watcher.on('add', handleChange)\n watcher.on('change', handleChange)\n watcher.on('unlink', handleChange)\n watcher.on('addDir', handleChange)\n watcher.on('unlinkDir', handleChange)\n\n return watcher\n}","import matter from 'gray-matter'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighter, Highlighter } from 'shiki'\nimport { SkillDirectory, SkillFile, SiteConfig, DocGenConfig, Navigation } from '../types/index.js'\n\nlet highlighter: Highlighter | null = null\n\nasync function getHighlighter() {\n if (!highlighter) {\n highlighter = await createHighlighter({\n themes: ['github-dark', 'github-light'],\n langs: ['javascript', 'typescript', 'bash', 'shell', 'json', 'html', 'css', 'vue', 'jsx', 'tsx', 'python', 'markdown', 'yaml', 'sql', 'go', 'rust', 'java', 'c', 'cpp']\n })\n }\n return highlighter\n}\n\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n typographer: true,\n highlight: function (str: string, lang: string) {\n // Synchronous fallback - actual highlighting done in enhanceFileContent\n return `<pre class=\"shiki-pending\" data-lang=\"${lang || 'text'}\"><code>${md.utils.escapeHtml(str)}</code></pre>`\n }\n})\n\nexport async function parseSkillsToConfig(\n directories: SkillDirectory[],\n siteConfig: SiteConfig\n): Promise<DocGenConfig> {\n const files: SkillFile[] = []\n const navigation = await generateNavigation(directories)\n\n // Collect all files for search indexing\n collectAllFiles(directories, files)\n\n // Enhance files with parsed content\n for (const file of files) {\n await enhanceFileContent(file)\n }\n\n return {\n siteConfig,\n navigation,\n files,\n directories\n }\n}\n\nfunction collectAllFiles(items: (SkillDirectory | SkillFile)[], files: SkillFile[]) {\n for (const item of items) {\n if ('content' in item) {\n // It's a SkillFile\n files.push(item)\n } else {\n // It's a SkillDirectory\n if (item.skillFile) {\n files.push(item.skillFile)\n }\n collectAllFiles(item.children, files)\n }\n }\n}\n\nasync function enhanceFileContent(file: SkillFile) {\n try {\n let content = file.content\n\n // Update title and description from frontmatter if available\n file.title = file.frontmatter.title || file.title\n file.description = file.frontmatter.description || file.description\n\n // Remove duplicate h1 if it matches frontmatter title\n if (file.frontmatter.title) {\n // Match first h1 heading in content (may have leading whitespace/newlines)\n const h1Match = content.match(/^\\s*#\\s+(.+)$/m)\n if (h1Match) {\n const h1Text = h1Match[1].trim()\n // If h1 matches title, remove it to avoid duplication\n if (h1Text === file.frontmatter.title) {\n content = content.replace(/^\\s*#\\s+.+\\n*/, '')\n }\n }\n }\n\n // Render markdown to HTML\n let html = md.render(content)\n \n // Apply syntax highlighting with shiki\n html = await highlightCodeBlocks(html)\n file.frontmatter.html = html\n\n // Extract headings for TOC\n const headings = extractHeadings(content)\n file.frontmatter.headings = headings\n\n } catch (error) {\n console.warn(`Failed to enhance content for ${file.path}:`, error)\n try {\n file.frontmatter.html = md.render(file.content)\n } catch (e) {\n console.error(`Failed to render markdown for ${file.path}:`, e)\n }\n }\n}\n\nasync function highlightCodeBlocks(html: string): Promise<string> {\n const hl = await getHighlighter()\n \n // Find all pending shiki code blocks and highlight them\n const codeBlockRegex = /<pre class=\"shiki-pending\" data-lang=\"([^\"]*)\"[^>]*><code>([^]*?)<\\/code><\\/pre>/g\n \n const matches = [...html.matchAll(codeBlockRegex)]\n \n for (const match of matches) {\n const [fullMatch, lang, escapedCode] = match\n // Unescape HTML entities\n const code = escapedCode\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n \n try {\n const validLang = hl.getLoadedLanguages().includes(lang) ? lang : 'text'\n const highlighted = hl.codeToHtml(code, {\n lang: validLang,\n theme: 'github-dark'\n })\n html = html.replace(fullMatch, highlighted)\n } catch (e) {\n // Keep original if highlighting fails\n console.warn(`Failed to highlight ${lang}:`, e)\n }\n }\n \n return html\n}\n\nfunction extractHeadings(content: string) {\n const headings: Array<{ level: number; text: string; anchor: string }> = []\n const lines = content.split('\\n')\n\n for (const line of lines) {\n const match = line.match(/^(#{1,6})\\\\s+(.+)$/)\n if (match) {\n const level = match[1].length\n const text = match[2].trim()\n const anchor = text.toLowerCase()\n .replace(/[^\\\\w\\\\s-]/g, '')\n .replace(/\\\\s+/g, '-')\n .trim()\n\n headings.push({ level, text, anchor })\n }\n }\n\n return headings\n}\n\nasync function generateNavigation(directories: SkillDirectory[]): Promise<Navigation[]> {\n const navigation: Navigation[] = []\n\n for (const dir of directories) {\n const navItem: Navigation = {\n text: dir.skillFile?.title || formatDirName(dir.name),\n link: dir.skillFile ? getFileRoute(dir.skillFile) : undefined\n }\n\n if (dir.children.length > 0) {\n navItem.children = []\n \n for (const child of dir.children) {\n if ('content' in child) {\n // It's a file\n navItem.children.push({\n text: child.title || formatFileName(child.name),\n link: getFileRoute(child)\n })\n } else {\n // It's a subdirectory\n const subNav = await generateNavigation([child])\n navItem.children.push(...subNav)\n }\n }\n }\n\n navigation.push(navItem)\n }\n\n return navigation\n}\n\nfunction getFileRoute(file: SkillFile): string {\n // Import the utility function from client utils\n // For now, use inline implementation\n const filePath = file.path\n \n // Try common patterns\n const patterns = ['my-docs', 'docs', 'documentation', '.claude/skills']\n let relativePath = ''\n \n for (const pattern of patterns) {\n const index = filePath.indexOf(pattern)\n if (index !== -1) {\n relativePath = filePath.slice(index + pattern.length)\n break\n }\n }\n \n if (!relativePath) {\n // Fallback: use last 2 segments\n const segments = filePath.split('/').filter(Boolean)\n if (segments.length >= 2) {\n relativePath = '/' + segments.slice(-2).join('/')\n } else {\n return '/'\n }\n }\n \n const segments = relativePath.split('/').filter(Boolean)\n \n if (segments.length === 0) return '/'\n \n // Remove file extension\n const lastSegment = segments[segments.length - 1]\n if (lastSegment.endsWith('.md')) {\n segments[segments.length - 1] = lastSegment.slice(0, -3)\n }\n \n // SKILL.md and README.md should map to parent directory route\n const finalSegment = segments[segments.length - 1]\n if (finalSegment === 'SKILL' || finalSegment === 'README') {\n segments.pop()\n }\n \n return '/' + segments.join('/')\n}\n\nfunction formatDirName(name: string): string {\n return name.split('-').map(word => \n word.charAt(0).toUpperCase() + word.slice(1)\n ).join(' ')\n}\n\nfunction formatFileName(name: string): string {\n const baseName = name.replace('.md', '')\n return formatDirName(baseName)\n}\n\nexport { md as markdownRenderer }","#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { previewCommand } from './commands/preview.js'\n\nconst program = new Command()\n\nprogram\n .name('docmk')\n .description('CLI tool for generating documentation from any directory')\n .version('1.0.0')\n .argument('[directory]', 'Source directory path (starts dev server)', './docs')\n .option('-p, --port <port>', 'Port to run dev server on', '3000')\n .action((directory, options) => {\n // Default action: start dev server\n devCommand({ dir: directory, port: options.port })\n })\n\nprogram\n .command('dev')\n .description('Start development server')\n .option('-p, --port <port>', 'Port to run dev server on', '3000')\n .option('-d, --dir <directory>', 'Source directory path', './docs')\n .action(devCommand)\n\nprogram\n .command('build')\n .description('Build static documentation site')\n .option('-d, --dir <directory>', 'Source directory path', './docs')\n .option('-o, --output <directory>', 'Output directory', 'dist')\n .action(buildCommand)\n\nprogram\n .command('preview')\n .description('Preview built documentation site')\n .option('-p, --port <port>', 'Port to run preview server on', '4173')\n .option('-o, --output <directory>', 'Built site directory', 'dist')\n .action(previewCommand)\n\nprogram.parse()","import path from 'path'\nimport { createViteDevServer } from '../../builder/vite-dev.js'\nimport { scanSkillsDirectory } from '../../scanner/index.js'\nimport { parseSkillsToConfig } from '../../parser/index.js'\n\ninterface DevOptions {\n port: string\n dir: string\n}\n\nexport async function devCommand(options: DevOptions) {\n console.log('šŸš€ Starting DocGen development server...')\n \n const sourceDir = path.resolve(process.cwd(), options.dir)\n const port = parseInt(options.port, 10)\n \n try {\n // Check if source directory exists\n console.log(`šŸ“ Scanning source directory: ${sourceDir}`)\n const directories = await scanSkillsDirectory(sourceDir)\n \n console.log(`āœ… Found ${directories.length} directories`)\n \n // Parse to config\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir: 'dist'\n })\n \n // Start Vite dev server\n const server = await createViteDevServer({\n port,\n skillsDir: sourceDir,\n config\n })\n \n console.log(`šŸŽ‰ Dev server running at http://localhost:${port}`)\n \n // Handle graceful shutdown\n process.on('SIGINT', async () => {\n console.log('\\\\nšŸ‘‹ Shutting down dev server...')\n await server.close()\n process.exit(0)\n })\n \n } catch (error) {\n console.error('āŒ Failed to start dev server:', error)\n process.exit(1)\n }\n}","import { createServer, ViteDevServer } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport path from 'path'\nimport { DocGenConfig } from '../types/index.js'\nimport { scanSkillsDirectory, watchSkillsDirectory } from '../scanner/index.js'\nimport { parseSkillsToConfig } from '../parser/index.js'\n\ninterface DevServerOptions {\n port: number\n skillsDir: string\n config: DocGenConfig\n}\n\nexport async function createViteDevServer(options: DevServerOptions): Promise<ViteDevServer> {\n let currentConfig = options.config\n\n const server = await createServer({\n root: path.resolve(process.cwd(), 'src/client'),\n server: {\n port: options.port,\n host: 'localhost'\n },\n publicDir: false, // Disable public dir in dev mode\n plugins: [\n vue(),\n // Custom plugin to inject config and handle API routes\n {\n name: 'docgen-dev',\n configureServer(server) {\n // API endpoint for configuration\n server.middlewares.use('/api/config', (req, res, next) => {\n if (req.method === 'GET') {\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(currentConfig))\n } else {\n next()\n }\n })\n\n // SPA fallback - return index.html for all non-API routes\n return () => {\n server.middlewares.use((req, res, next) => {\n // Skip API routes and vite's own routes\n if (req.url?.startsWith('/api/') || req.url?.startsWith('/@') || req.url?.includes('.html')) {\n return next()\n }\n // For all other routes, serve index.html for SPA routing\n if (req.url && !req.url.includes('.')) {\n req.url = '/index.html'\n }\n next()\n })\n }\n },\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n // Inject lightweight config placeholder\n // Full config will be loaded via API to avoid HTML parsing issues\n const configScript = `\n <script>\n // Config will be loaded from /api/config\n globalThis.__DOCGEN_CONFIG__ = null;\n </script>\n `\n return html.replace('<head>', `<head>${configScript}`)\n }\n }\n }\n ],\n resolve: {\n alias: {\n '@': path.resolve(process.cwd(), 'src/client')\n }\n },\n define: {\n __DOCGEN_CONFIG__: JSON.stringify(currentConfig)\n }\n })\n\n // Watch skills directory for changes\n const watcher = await watchSkillsDirectory(options.skillsDir, async (directories) => {\n console.log('šŸ“ Skills directory changed, updating configuration...')\n \n try {\n currentConfig = await parseSkillsToConfig(directories, currentConfig.siteConfig)\n \n // Notify all connected clients to reload\n server.ws.send({\n type: 'full-reload'\n })\n \n console.log('āœ… Configuration updated')\n } catch (error) {\n console.error('āŒ Failed to update configuration:', error)\n \n // Send error to clients\n server.ws.send({\n type: 'error',\n err: {\n message: `Failed to update configuration: ${error.message}`,\n stack: error.stack\n }\n })\n }\n })\n\n // Start the server\n await server.listen()\n\n // Extend server with cleanup method\n const originalClose = server.close.bind(server)\n server.close = async () => {\n await watcher?.close()\n return originalClose()\n }\n\n return server\n}\n\nexport async function createProductionBuild() {\n // This will be implemented in the builder\n}","import path from 'path'\nimport { buildSite } from '../../builder/index.js'\nimport { scanSkillsDirectory } from '../../scanner/index.js'\nimport { parseSkillsToConfig } from '../../parser/index.js'\n\ninterface BuildOptions {\n dir: string\n output: string\n}\n\nexport async function buildCommand(options: BuildOptions) {\n console.log('šŸ—ļø Building DocGen documentation site...')\n \n const sourceDir = path.resolve(process.cwd(), options.dir)\n const outputDir = path.resolve(process.cwd(), options.output)\n \n try {\n // Scan source directory\n console.log(`šŸ“ Scanning source directory: ${sourceDir}`)\n const directories = await scanSkillsDirectory(sourceDir)\n \n console.log(`āœ… Found ${directories.length} directories`)\n \n // Parse to config\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir\n })\n \n // Build site\n console.log(`šŸ“¦ Building to: ${outputDir}`)\n await buildSite({\n input: sourceDir,\n output: outputDir,\n mode: 'production'\n }, config)\n \n console.log('āœ… Build completed successfully!')\n console.log(`šŸ“‚ Built files are in: ${outputDir}`)\n \n } catch (error) {\n console.error('āŒ Build failed:', error)\n process.exit(1)\n }\n}","import { build } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport path from 'path'\nimport fs from 'fs/promises'\nimport { DocGenConfig, BuildOptions } from '../types/index.js'\n\nexport async function buildSite(options: BuildOptions, config: DocGenConfig) {\n console.log('šŸ—ļø Building documentation site...')\n \n // Ensure output directory exists\n await fs.mkdir(options.output, { recursive: true })\n \n // Write config to a temporary file for the build process\n const configPath = path.join(process.cwd(), 'temp-config.json')\n await fs.writeFile(configPath, JSON.stringify(config, null, 2))\n \n try {\n // Build the client application\n await build({\n root: path.resolve(process.cwd(), 'src/client'),\n base: config.siteConfig.baseUrl,\n build: {\n outDir: options.output,\n emptyOutDir: true,\n rollupOptions: {\n input: {\n main: path.resolve(process.cwd(), 'src/client/index.html')\n }\n }\n },\n plugins: [\n vue(),\n // Plugin to inject config during build\n {\n name: 'docgen-build',\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n // Encode config as base64 with proper UTF-8 handling\n const configJson = JSON.stringify(config)\n // Use encodeURIComponent to handle UTF-8 properly before base64\n const utf8Encoded = unescape(encodeURIComponent(configJson))\n const configBase64 = Buffer.from(utf8Encoded, 'binary').toString('base64')\n // Decode: atob -> decodeURIComponent(escape()) to restore UTF-8\n const configScript = `<script>globalThis.__DOCGEN_CONFIG__=JSON.parse(decodeURIComponent(escape(atob(\"${configBase64}\"))));</script>`\n return html.replace('</head>', `${configScript}\\n</head>`)\n }\n }\n }\n ],\n resolve: {\n alias: {\n '@': path.resolve(process.cwd(), 'src/client')\n }\n },\n define: {\n __DOCGEN_CONFIG__: JSON.stringify(config)\n }\n })\n \n // Generate additional static files\n await generateSitemap(options.output, config)\n await generateRobotsTxt(options.output, config)\n await copyAssets(options.output)\n \n console.log('āœ… Build completed successfully!')\n \n } finally {\n // Clean up temporary config file\n try {\n await fs.unlink(configPath)\n } catch {\n // Ignore if file doesn't exist\n }\n }\n}\n\nasync function generateSitemap(outputDir: string, config: DocGenConfig) {\n console.log('šŸ“„ Generating sitemap...')\n \n const baseUrl = config.siteConfig.baseUrl.replace(/\\/$/, '')\n const urls: string[] = []\n \n // Add home page\n urls.push(`${baseUrl}/`)\n \n // Add all skill pages\n for (const file of config.files) {\n const route = getFileRoute(file.path, config.siteConfig.skillsDir)\n if (route !== '/') {\n urls.push(`${baseUrl}${route}`)\n }\n }\n \n const sitemap = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urls.map(url => ` <url>\n <loc>${url}</loc>\n <lastmod>${new Date().toISOString().split('T')[0]}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n </url>`).join('\\\\n')}\n</urlset>`\n \n await fs.writeFile(path.join(outputDir, 'sitemap.xml'), sitemap)\n}\n\nasync function generateRobotsTxt(outputDir: string, config: DocGenConfig) {\n console.log('šŸ¤– Generating robots.txt...')\n \n const baseUrl = config.siteConfig.baseUrl.replace(/\\/$/, '')\n const robotsTxt = `User-agent: *\nAllow: /\n\nSitemap: ${baseUrl}/sitemap.xml`\n \n await fs.writeFile(path.join(outputDir, 'robots.txt'), robotsTxt)\n}\n\nasync function copyAssets(outputDir: string) {\n console.log('šŸ“ Copying static assets...')\n \n // Create a simple favicon if it doesn't exist\n const faviconPath = path.join(outputDir, 'favicon.ico')\n \n try {\n await fs.access(faviconPath)\n } catch {\n // Create a simple SVG favicon\n const faviconSvg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\">\n <rect width=\"32\" height=\"32\" rx=\"4\" fill=\"#3182ce\"/>\n <text x=\"16\" y=\"22\" text-anchor=\"middle\" fill=\"white\" font-family=\"system-ui\" font-size=\"18\" font-weight=\"bold\">D</text>\n</svg>`\n \n await fs.writeFile(path.join(outputDir, 'favicon.svg'), faviconSvg)\n }\n}\n\nfunction getFileRoute(filePath: string, baseDir: string): string {\n // Normalize paths for comparison\n const normalizedFilePath = path.normalize(filePath)\n const normalizedBaseDir = path.normalize(baseDir)\n \n // Check if file is within base directory\n if (!normalizedFilePath.startsWith(normalizedBaseDir)) {\n return '/'\n }\n \n // Get relative path from base directory\n const relativePath = normalizedFilePath.slice(normalizedBaseDir.length)\n const segments = relativePath.split(path.sep).filter(Boolean)\n \n if (segments.length === 0) return '/'\n \n const lastSegment = segments[segments.length - 1]\n if (lastSegment.endsWith('.md')) {\n segments[segments.length - 1] = lastSegment.slice(0, -3)\n }\n \n // SKILL.md and README.md should map to parent directory route\n const finalSegment = segments[segments.length - 1]\n if (finalSegment === 'SKILL' || finalSegment === 'README') {\n segments.pop()\n }\n\n return '/' + segments.join('/')\n}\n\nexport async function buildForProduction(sourceDir: string, outputDir: string): Promise<DocGenConfig> {\n const { scanSkillsDirectory } = await import('../scanner/index.js')\n const { parseSkillsToConfig } = await import('../parser/index.js')\n \n const directories = await scanSkillsDirectory(sourceDir)\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir\n })\n \n await buildSite({\n input: sourceDir,\n output: outputDir,\n mode: 'production'\n }, config)\n \n return config\n}","import path from 'path'\nimport fs from 'fs/promises'\nimport sirv from 'sirv'\nimport { createServer } from 'http'\n\ninterface PreviewOptions {\n port: string\n output: string\n}\n\nexport async function previewCommand(options: PreviewOptions) {\n console.log('šŸ‘€ Starting DocGen preview server...')\n \n const outputDir = path.resolve(process.cwd(), options.output)\n const port = parseInt(options.port, 10)\n \n try {\n // Check if build directory exists\n try {\n await fs.access(outputDir)\n } catch {\n console.error(`āŒ Build directory not found: ${outputDir}`)\n console.log('šŸ’” Run \"docgen build\" first to generate the static site')\n process.exit(1)\n }\n \n // Create static file server\n const serve = sirv(outputDir, {\n single: true, // SPA mode\n dev: false,\n setHeaders: (res, pathname) => {\n if (pathname.endsWith('.html') || pathname === '/') {\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n }\n }\n })\n \n const server = createServer(serve)\n \n server.listen(port, () => {\n console.log(`šŸŽ‰ Preview server running at http://localhost:${port}`)\n console.log(`šŸ“‚ Serving files from: ${outputDir}`)\n })\n \n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\\\nšŸ‘‹ Shutting down preview server...')\n server.close(() => {\n process.exit(0)\n })\n })\n \n } catch (error) {\n console.error('āŒ Failed to start preview server:', error)\n process.exit(1)\n }\n}"],"mappings":";;;;;;;AAAA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGjB,eAAsB,oBAAoB,WAA8C;AACtF,MAAI;AACF,UAAM,GAAG,OAAO,SAAS;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI,MAAM,+BAA+B,SAAS,EAAE;AAAA,EAC5D;AAEA,QAAM,UAAU,MAAM,GAAG,QAAQ,WAAW,EAAE,eAAe,KAAK,CAAC;AACnE,QAAM,cAAgC,CAAC;AAEvC,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,UAAU,KAAK,KAAK,WAAW,MAAM,IAAI;AAC/C,YAAM,iBAAiB,MAAM,cAAc,SAAS,MAAM,IAAI;AAC9D,kBAAY,KAAK,cAAc;AAAA,IACjC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,cAAc,SAAiB,MAAuC;AACnF,QAAM,UAAU,MAAM,GAAG,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AACjE,QAAM,WAA2C,CAAC;AAClD,MAAI;AAEJ,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAY,KAAK,KAAK,SAAS,MAAM,IAAI;AAE/C,QAAI,MAAM,YAAY,GAAG;AACvB,YAAM,SAAS,MAAM,cAAc,WAAW,MAAM,IAAI;AACxD,eAAS,KAAK,MAAM;AAAA,IACtB,WAAW,MAAM,OAAO,KAAK,MAAM,KAAK,SAAS,KAAK,GAAG;AACvD,YAAM,OAAO,MAAM,kBAAkB,WAAW,MAAM,IAAI;AAE1D,UAAI,MAAM,SAAS,YAAY;AAC7B,oBAAY;AAAA,MACd,OAAO;AACL,iBAAS,KAAK,IAAI;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,kBAAkB,UAAkB,UAAsC;AACvF,QAAM,UAAU,MAAM,GAAG,SAAS,UAAU,OAAO;AACnD,QAAM,QAAQ,MAAM,GAAG,KAAK,QAAQ;AAGpC,QAAM,mBAAmB,QAAQ,MAAM,kCAAkC;AACzE,QAAM,cAAmC,CAAC;AAC1C,MAAI,kBAAkB;AAEtB,MAAI,kBAAkB;AAEpB,sBAAkB,QAAQ,MAAM,iBAAiB,CAAC,EAAE,MAAM;AAG1D,UAAM,UAAU,iBAAiB,CAAC,EAAE,MAAM,OAAO;AACjD,eAAW,QAAQ,SAAS;AAC1B,YAAM,aAAa,KAAK,QAAQ,GAAG;AACnC,UAAI,aAAa,GAAG;AAClB,cAAM,MAAM,KAAK,MAAM,GAAG,UAAU,EAAE,KAAK;AAC3C,cAAM,QAAQ,KAAK,MAAM,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,gBAAgB,EAAE;AAC1E,YAAI,OAAO,OAAO;AAChB,sBAAY,GAAG,IAAI;AAAA,QACrB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAO,YAAY,SAAS,SAAS,QAAQ,OAAO,EAAE;AAAA,IACtD,aAAa,YAAY;AAAA,IACzB,SAAS;AAAA,IACT;AAAA,IACA,cAAc,MAAM,MAAM,QAAQ;AAAA,EACpC;AACF;AAEA,eAAsB,qBACpB,WACA,UACA;AACA,QAAM,WAAW,MAAM,OAAO,UAAU;AAExC,QAAM,UAAU,SAAS,MAAM,WAAW;AAAA,IACxC,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,eAAe;AAAA,EACjB,CAAC;AAED,MAAI;AAEJ,QAAM,eAAe,MAAM;AACzB,iBAAa,aAAa;AAC1B,oBAAgB,WAAW,YAAY;AACrC,UAAI;AACF,cAAM,cAAc,MAAM,oBAAoB,SAAS;AACvD,iBAAS,WAAW;AAAA,MACtB,SAAS,OAAO;AACd,gBAAQ,MAAM,sCAAsC,KAAK;AAAA,MAC3D;AAAA,IACF,GAAG,GAAG;AAAA,EACR;AAEA,UAAQ,GAAG,OAAO,YAAY;AAC9B,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,UAAU,YAAY;AACjC,UAAQ,GAAG,aAAa,YAAY;AAEpC,SAAO;AACT;AA9HA;AAAA;AAAA;AAAA;AAAA;;;ACCA,OAAO,gBAAgB;AACvB,SAAS,yBAAsC;AAK/C,eAAe,iBAAiB;AAC9B,MAAI,CAAC,aAAa;AAChB,kBAAc,MAAM,kBAAkB;AAAA,MACpC,QAAQ,CAAC,eAAe,cAAc;AAAA,MACtC,OAAO,CAAC,cAAc,cAAc,QAAQ,SAAS,QAAQ,QAAQ,OAAO,OAAO,OAAO,OAAO,UAAU,YAAY,QAAQ,OAAO,MAAM,QAAQ,QAAQ,KAAK,KAAK;AAAA,IACxK,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAYA,eAAsB,oBACpB,aACA,YACuB;AACvB,QAAM,QAAqB,CAAC;AAC5B,QAAM,aAAa,MAAM,mBAAmB,WAAW;AAGvD,kBAAgB,aAAa,KAAK;AAGlC,aAAW,QAAQ,OAAO;AACxB,UAAM,mBAAmB,IAAI;AAAA,EAC/B;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAAuC,OAAoB;AAClF,aAAW,QAAQ,OAAO;AACxB,QAAI,aAAa,MAAM;AAErB,YAAM,KAAK,IAAI;AAAA,IACjB,OAAO;AAEL,UAAI,KAAK,WAAW;AAClB,cAAM,KAAK,KAAK,SAAS;AAAA,MAC3B;AACA,sBAAgB,KAAK,UAAU,KAAK;AAAA,IACtC;AAAA,EACF;AACF;AAEA,eAAe,mBAAmB,MAAiB;AACjD,MAAI;AACF,QAAI,UAAU,KAAK;AAGnB,SAAK,QAAQ,KAAK,YAAY,SAAS,KAAK;AAC5C,SAAK,cAAc,KAAK,YAAY,eAAe,KAAK;AAGxD,QAAI,KAAK,YAAY,OAAO;AAE1B,YAAM,UAAU,QAAQ,MAAM,gBAAgB;AAC9C,UAAI,SAAS;AACX,cAAM,SAAS,QAAQ,CAAC,EAAE,KAAK;AAE/B,YAAI,WAAW,KAAK,YAAY,OAAO;AACrC,oBAAU,QAAQ,QAAQ,iBAAiB,EAAE;AAAA,QAC/C;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,GAAG,OAAO,OAAO;AAG5B,WAAO,MAAM,oBAAoB,IAAI;AACrC,SAAK,YAAY,OAAO;AAGxB,UAAM,WAAW,gBAAgB,OAAO;AACxC,SAAK,YAAY,WAAW;AAAA,EAE9B,SAAS,OAAO;AACd,YAAQ,KAAK,iCAAiC,KAAK,IAAI,KAAK,KAAK;AACjE,QAAI;AACF,WAAK,YAAY,OAAO,GAAG,OAAO,KAAK,OAAO;AAAA,IAChD,SAAS,GAAG;AACV,cAAQ,MAAM,iCAAiC,KAAK,IAAI,KAAK,CAAC;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,oBAAoB,MAA+B;AAChE,QAAM,KAAK,MAAM,eAAe;AAGhC,QAAM,iBAAiB;AAEvB,QAAM,UAAU,CAAC,GAAG,KAAK,SAAS,cAAc,CAAC;AAEjD,aAAW,SAAS,SAAS;AAC3B,UAAM,CAAC,WAAW,MAAM,WAAW,IAAI;AAEvC,UAAM,OAAO,YACV,QAAQ,SAAS,GAAG,EACpB,QAAQ,SAAS,GAAG,EACpB,QAAQ,UAAU,GAAG,EACrB,QAAQ,WAAW,GAAG,EACtB,QAAQ,UAAU,GAAG;AAExB,QAAI;AACF,YAAM,YAAY,GAAG,mBAAmB,EAAE,SAAS,IAAI,IAAI,OAAO;AAClE,YAAM,cAAc,GAAG,WAAW,MAAM;AAAA,QACtC,MAAM;AAAA,QACN,OAAO;AAAA,MACT,CAAC;AACD,aAAO,KAAK,QAAQ,WAAW,WAAW;AAAA,IAC5C,SAAS,GAAG;AAEV,cAAQ,KAAK,uBAAuB,IAAI,KAAK,CAAC;AAAA,IAChD;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,SAAiB;AACxC,QAAM,WAAmE,CAAC;AAC1E,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAEhC,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,KAAK,MAAM,oBAAoB;AAC7C,QAAI,OAAO;AACT,YAAM,QAAQ,MAAM,CAAC,EAAE;AACvB,YAAM,OAAO,MAAM,CAAC,EAAE,KAAK;AAC3B,YAAM,SAAS,KAAK,YAAY,EAC7B,QAAQ,eAAe,EAAE,EACzB,QAAQ,SAAS,GAAG,EACpB,KAAK;AAER,eAAS,KAAK,EAAE,OAAO,MAAM,OAAO,CAAC;AAAA,IACvC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,mBAAmB,aAAsD;AACtF,QAAM,aAA2B,CAAC;AAElC,aAAW,OAAO,aAAa;AAC7B,UAAM,UAAsB;AAAA,MAC1B,MAAM,IAAI,WAAW,SAAS,cAAc,IAAI,IAAI;AAAA,MACpD,MAAM,IAAI,YAAY,aAAa,IAAI,SAAS,IAAI;AAAA,IACtD;AAEA,QAAI,IAAI,SAAS,SAAS,GAAG;AAC3B,cAAQ,WAAW,CAAC;AAEpB,iBAAW,SAAS,IAAI,UAAU;AAChC,YAAI,aAAa,OAAO;AAEtB,kBAAQ,SAAS,KAAK;AAAA,YACpB,MAAM,MAAM,SAAS,eAAe,MAAM,IAAI;AAAA,YAC9C,MAAM,aAAa,KAAK;AAAA,UAC1B,CAAC;AAAA,QACH,OAAO;AAEL,gBAAM,SAAS,MAAM,mBAAmB,CAAC,KAAK,CAAC;AAC/C,kBAAQ,SAAS,KAAK,GAAG,MAAM;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AAEA,eAAW,KAAK,OAAO;AAAA,EACzB;AAEA,SAAO;AACT;AAEA,SAAS,aAAa,MAAyB;AAG7C,QAAM,WAAW,KAAK;AAGtB,QAAM,WAAW,CAAC,WAAW,QAAQ,iBAAiB,gBAAgB;AACtE,MAAI,eAAe;AAEnB,aAAW,WAAW,UAAU;AAC9B,UAAM,QAAQ,SAAS,QAAQ,OAAO;AACtC,QAAI,UAAU,IAAI;AAChB,qBAAe,SAAS,MAAM,QAAQ,QAAQ,MAAM;AACpD;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AAEjB,UAAMA,YAAW,SAAS,MAAM,GAAG,EAAE,OAAO,OAAO;AACnD,QAAIA,UAAS,UAAU,GAAG;AACxB,qBAAe,MAAMA,UAAS,MAAM,EAAE,EAAE,KAAK,GAAG;AAAA,IAClD,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,WAAW,aAAa,MAAM,GAAG,EAAE,OAAO,OAAO;AAEvD,MAAI,SAAS,WAAW,EAAG,QAAO;AAGlC,QAAM,cAAc,SAAS,SAAS,SAAS,CAAC;AAChD,MAAI,YAAY,SAAS,KAAK,GAAG;AAC/B,aAAS,SAAS,SAAS,CAAC,IAAI,YAAY,MAAM,GAAG,EAAE;AAAA,EACzD;AAGA,QAAM,eAAe,SAAS,SAAS,SAAS,CAAC;AACjD,MAAI,iBAAiB,WAAW,iBAAiB,UAAU;AACzD,aAAS,IAAI;AAAA,EACf;AAEA,SAAO,MAAM,SAAS,KAAK,GAAG;AAChC;AAEA,SAAS,cAAc,MAAsB;AAC3C,SAAO,KAAK,MAAM,GAAG,EAAE;AAAA,IAAI,UACzB,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,EAC7C,EAAE,KAAK,GAAG;AACZ;AAEA,SAAS,eAAe,MAAsB;AAC5C,QAAM,WAAW,KAAK,QAAQ,OAAO,EAAE;AACvC,SAAO,cAAc,QAAQ;AAC/B;AA1PA,IAKI,aAYE;AAjBN;AAAA;AAAA;AAKA,IAAI,cAAkC;AAYtC,IAAM,KAAK,IAAI,WAAW;AAAA,MACxB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,aAAa;AAAA,MACb,WAAW,SAAU,KAAa,MAAc;AAE9C,eAAO,yCAAyC,QAAQ,MAAM,WAAW,GAAG,MAAM,WAAW,GAAG,CAAC;AAAA,MACnG;AAAA,IACF,CAAC;AAAA;AAAA;;;ACvBD,SAAS,eAAe;;;ACFxB,OAAOC,WAAU;;;ACIjB;AACA;AALA,SAAS,oBAAmC;AAC5C,OAAO,SAAS;AAChB,OAAOC,WAAU;AAWjB,eAAsB,oBAAoB,SAAmD;AAC3F,MAAI,gBAAgB,QAAQ;AAE5B,QAAM,SAAS,MAAM,aAAa;AAAA,IAChC,MAAMA,MAAK,QAAQ,QAAQ,IAAI,GAAG,YAAY;AAAA,IAC9C,QAAQ;AAAA,MACN,MAAM,QAAQ;AAAA,MACd,MAAM;AAAA,IACR;AAAA,IACA,WAAW;AAAA;AAAA,IACX,SAAS;AAAA,MACP,IAAI;AAAA;AAAA,MAEJ;AAAA,QACE,MAAM;AAAA,QACN,gBAAgBC,SAAQ;AAEtB,UAAAA,QAAO,YAAY,IAAI,eAAe,CAAC,KAAK,KAAK,SAAS;AACxD,gBAAI,IAAI,WAAW,OAAO;AACxB,kBAAI,UAAU,gBAAgB,kBAAkB;AAChD,kBAAI,IAAI,KAAK,UAAU,aAAa,CAAC;AAAA,YACvC,OAAO;AACL,mBAAK;AAAA,YACP;AAAA,UACF,CAAC;AAGD,iBAAO,MAAM;AACX,YAAAA,QAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AAEzC,kBAAI,IAAI,KAAK,WAAW,OAAO,KAAK,IAAI,KAAK,WAAW,IAAI,KAAK,IAAI,KAAK,SAAS,OAAO,GAAG;AAC3F,uBAAO,KAAK;AAAA,cACd;AAEA,kBAAI,IAAI,OAAO,CAAC,IAAI,IAAI,SAAS,GAAG,GAAG;AACrC,oBAAI,MAAM;AAAA,cACZ;AACA,mBAAK;AAAA,YACP,CAAC;AAAA,UACH;AAAA,QACF;AAAA,QACA,oBAAoB;AAAA,UAClB,OAAO;AAAA,UACP,QAAQ,MAAM;AAGZ,kBAAM,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAMrB,mBAAO,KAAK,QAAQ,UAAU,SAAS,YAAY,EAAE;AAAA,UACvD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,OAAO;AAAA,QACL,KAAKD,MAAK,QAAQ,QAAQ,IAAI,GAAG,YAAY;AAAA,MAC/C;AAAA,IACF;AAAA,IACA,QAAQ;AAAA,MACN,mBAAmB,KAAK,UAAU,aAAa;AAAA,IACjD;AAAA,EACF,CAAC;AAGD,QAAM,UAAU,MAAM,qBAAqB,QAAQ,WAAW,OAAO,gBAAgB;AACnF,YAAQ,IAAI,+DAAwD;AAEpE,QAAI;AACF,sBAAgB,MAAM,oBAAoB,aAAa,cAAc,UAAU;AAG/E,aAAO,GAAG,KAAK;AAAA,QACb,MAAM;AAAA,MACR,CAAC;AAED,cAAQ,IAAI,8BAAyB;AAAA,IACvC,SAAS,OAAO;AACd,cAAQ,MAAM,0CAAqC,KAAK;AAGxD,aAAO,GAAG,KAAK;AAAA,QACb,MAAM;AAAA,QACN,KAAK;AAAA,UACH,SAAS,mCAAmC,MAAM,OAAO;AAAA,UACzD,OAAO,MAAM;AAAA,QACf;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAGD,QAAM,OAAO,OAAO;AAGpB,QAAM,gBAAgB,OAAO,MAAM,KAAK,MAAM;AAC9C,SAAO,QAAQ,YAAY;AACzB,UAAM,SAAS,MAAM;AACrB,WAAO,cAAc;AAAA,EACvB;AAEA,SAAO;AACT;;;ADpHA;AACA;AAOA,eAAsB,WAAW,SAAqB;AACpD,UAAQ,IAAI,iDAA0C;AAEtD,QAAM,YAAYE,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,GAAG;AACzD,QAAM,OAAO,SAAS,QAAQ,MAAM,EAAE;AAEtC,MAAI;AAEF,YAAQ,IAAI,wCAAiC,SAAS,EAAE;AACxD,UAAM,cAAc,MAAM,oBAAoB,SAAS;AAEvD,YAAQ,IAAI,gBAAW,YAAY,MAAM,cAAc;AAGvD,UAAM,SAAS,MAAM,oBAAoB,aAAa;AAAA,MACpD,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AAGD,UAAM,SAAS,MAAM,oBAAoB;AAAA,MACvC;AAAA,MACA,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AAED,YAAQ,IAAI,oDAA6C,IAAI,EAAE;AAG/D,YAAQ,GAAG,UAAU,YAAY;AAC/B,cAAQ,IAAI,0CAAmC;AAC/C,YAAM,OAAO,MAAM;AACnB,cAAQ,KAAK,CAAC;AAAA,IAChB,CAAC;AAAA,EAEH,SAAS,OAAO;AACd,YAAQ,MAAM,sCAAiC,KAAK;AACpD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AEpDA,OAAOC,WAAU;;;ACAjB,SAAS,aAAa;AACtB,OAAOC,UAAS;AAChB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAGf,eAAsB,UAAU,SAAuB,QAAsB;AAC3E,UAAQ,IAAI,iDAAqC;AAGjD,QAAMA,IAAG,MAAM,QAAQ,QAAQ,EAAE,WAAW,KAAK,CAAC;AAGlD,QAAM,aAAaD,MAAK,KAAK,QAAQ,IAAI,GAAG,kBAAkB;AAC9D,QAAMC,IAAG,UAAU,YAAY,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAE9D,MAAI;AAEF,UAAM,MAAM;AAAA,MACV,MAAMD,MAAK,QAAQ,QAAQ,IAAI,GAAG,YAAY;AAAA,MAC9C,MAAM,OAAO,WAAW;AAAA,MACxB,OAAO;AAAA,QACL,QAAQ,QAAQ;AAAA,QAChB,aAAa;AAAA,QACb,eAAe;AAAA,UACb,OAAO;AAAA,YACL,MAAMA,MAAK,QAAQ,QAAQ,IAAI,GAAG,uBAAuB;AAAA,UAC3D;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACPD,KAAI;AAAA;AAAA,QAEJ;AAAA,UACE,MAAM;AAAA,UACN,oBAAoB;AAAA,YAClB,OAAO;AAAA,YACP,QAAQ,MAAM;AAEZ,oBAAM,aAAa,KAAK,UAAU,MAAM;AAExC,oBAAM,cAAc,SAAS,mBAAmB,UAAU,CAAC;AAC3D,oBAAM,eAAe,OAAO,KAAK,aAAa,QAAQ,EAAE,SAAS,QAAQ;AAEzE,oBAAM,eAAe,mFAAmF,YAAY;AACpH,qBAAO,KAAK,QAAQ,WAAW,GAAG,YAAY;AAAA,QAAW;AAAA,YAC3D;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,UACL,KAAKC,MAAK,QAAQ,QAAQ,IAAI,GAAG,YAAY;AAAA,QAC/C;AAAA,MACF;AAAA,MACA,QAAQ;AAAA,QACN,mBAAmB,KAAK,UAAU,MAAM;AAAA,MAC1C;AAAA,IACF,CAAC;AAGD,UAAM,gBAAgB,QAAQ,QAAQ,MAAM;AAC5C,UAAM,kBAAkB,QAAQ,QAAQ,MAAM;AAC9C,UAAM,WAAW,QAAQ,MAAM;AAE/B,YAAQ,IAAI,sCAAiC;AAAA,EAE/C,UAAE;AAEA,QAAI;AACF,YAAMC,IAAG,OAAO,UAAU;AAAA,IAC5B,QAAQ;AAAA,IAER;AAAA,EACF;AACF;AAEA,eAAe,gBAAgB,WAAmB,QAAsB;AACtE,UAAQ,IAAI,iCAA0B;AAEtC,QAAM,UAAU,OAAO,WAAW,QAAQ,QAAQ,OAAO,EAAE;AAC3D,QAAM,OAAiB,CAAC;AAGxB,OAAK,KAAK,GAAG,OAAO,GAAG;AAGvB,aAAW,QAAQ,OAAO,OAAO;AAC/B,UAAM,QAAQC,cAAa,KAAK,MAAM,OAAO,WAAW,SAAS;AACjE,QAAI,UAAU,KAAK;AACjB,WAAK,KAAK,GAAG,OAAO,GAAG,KAAK,EAAE;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,UAAU;AAAA;AAAA,EAEhB,KAAK,IAAI,SAAO;AAAA,WACP,GAAG;AAAA,gBACC,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA;AAAA;AAAA,SAG5C,EAAE,KAAK,KAAK,CAAC;AAAA;AAGpB,QAAMD,IAAG,UAAUD,MAAK,KAAK,WAAW,aAAa,GAAG,OAAO;AACjE;AAEA,eAAe,kBAAkB,WAAmB,QAAsB;AACxE,UAAQ,IAAI,oCAA6B;AAEzC,QAAM,UAAU,OAAO,WAAW,QAAQ,QAAQ,OAAO,EAAE;AAC3D,QAAM,YAAY;AAAA;AAAA;AAAA,WAGT,OAAO;AAEhB,QAAMC,IAAG,UAAUD,MAAK,KAAK,WAAW,YAAY,GAAG,SAAS;AAClE;AAEA,eAAe,WAAW,WAAmB;AAC3C,UAAQ,IAAI,oCAA6B;AAGzC,QAAM,cAAcA,MAAK,KAAK,WAAW,aAAa;AAEtD,MAAI;AACF,UAAMC,IAAG,OAAO,WAAW;AAAA,EAC7B,QAAQ;AAEN,UAAM,aAAa;AAAA;AAAA;AAAA;AAKnB,UAAMA,IAAG,UAAUD,MAAK,KAAK,WAAW,aAAa,GAAG,UAAU;AAAA,EACpE;AACF;AAEA,SAASE,cAAa,UAAkB,SAAyB;AAE/D,QAAM,qBAAqBF,MAAK,UAAU,QAAQ;AAClD,QAAM,oBAAoBA,MAAK,UAAU,OAAO;AAGhD,MAAI,CAAC,mBAAmB,WAAW,iBAAiB,GAAG;AACrD,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,mBAAmB,MAAM,kBAAkB,MAAM;AACtE,QAAM,WAAW,aAAa,MAAMA,MAAK,GAAG,EAAE,OAAO,OAAO;AAE5D,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,cAAc,SAAS,SAAS,SAAS,CAAC;AAChD,MAAI,YAAY,SAAS,KAAK,GAAG;AAC/B,aAAS,SAAS,SAAS,CAAC,IAAI,YAAY,MAAM,GAAG,EAAE;AAAA,EACzD;AAGA,QAAM,eAAe,SAAS,SAAS,SAAS,CAAC;AACjD,MAAI,iBAAiB,WAAW,iBAAiB,UAAU;AACzD,aAAS,IAAI;AAAA,EACf;AAEA,SAAO,MAAM,SAAS,KAAK,GAAG;AAChC;;;ADpKA;AACA;AAOA,eAAsB,aAAa,SAAuB;AACxD,UAAQ,IAAI,wDAA4C;AAExD,QAAM,YAAYG,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,GAAG;AACzD,QAAM,YAAYA,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM;AAE5D,MAAI;AAEF,YAAQ,IAAI,wCAAiC,SAAS,EAAE;AACxD,UAAM,cAAc,MAAM,oBAAoB,SAAS;AAEvD,YAAQ,IAAI,gBAAW,YAAY,MAAM,cAAc;AAGvD,UAAM,SAAS,MAAM,oBAAoB,aAAa;AAAA,MACpD,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,WAAW;AAAA,MACX;AAAA,IACF,CAAC;AAGD,YAAQ,IAAI,0BAAmB,SAAS,EAAE;AAC1C,UAAM,UAAU;AAAA,MACd,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM;AAAA,IACR,GAAG,MAAM;AAET,YAAQ,IAAI,sCAAiC;AAC7C,YAAQ,IAAI,iCAA0B,SAAS,EAAE;AAAA,EAEnD,SAAS,OAAO;AACd,YAAQ,MAAM,wBAAmB,KAAK;AACtC,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AE/CA,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AACf,OAAO,UAAU;AACjB,SAAS,gBAAAC,qBAAoB;AAO7B,eAAsB,eAAe,SAAyB;AAC5D,UAAQ,IAAI,6CAAsC;AAElD,QAAM,YAAYF,MAAK,QAAQ,QAAQ,IAAI,GAAG,QAAQ,MAAM;AAC5D,QAAM,OAAO,SAAS,QAAQ,MAAM,EAAE;AAEtC,MAAI;AAEF,QAAI;AACF,YAAMC,IAAG,OAAO,SAAS;AAAA,IAC3B,QAAQ;AACN,cAAQ,MAAM,qCAAgC,SAAS,EAAE;AACzD,cAAQ,IAAI,gEAAyD;AACrE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAGA,UAAM,QAAQ,KAAK,WAAW;AAAA,MAC5B,QAAQ;AAAA;AAAA,MACR,KAAK;AAAA,MACL,YAAY,CAAC,KAAK,aAAa;AAC7B,YAAI,SAAS,SAAS,OAAO,KAAK,aAAa,KAAK;AAClD,cAAI,UAAU,gBAAgB,0BAA0B;AAAA,QAC1D;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,SAASC,cAAa,KAAK;AAEjC,WAAO,OAAO,MAAM,MAAM;AACxB,cAAQ,IAAI,wDAAiD,IAAI,EAAE;AACnE,cAAQ,IAAI,iCAA0B,SAAS,EAAE;AAAA,IACnD,CAAC;AAGD,YAAQ,GAAG,UAAU,MAAM;AACzB,cAAQ,IAAI,8CAAuC;AACnD,aAAO,MAAM,MAAM;AACjB,gBAAQ,KAAK,CAAC;AAAA,MAChB,CAAC;AAAA,IACH,CAAC;AAAA,EAEH,SAAS,OAAO;AACd,YAAQ,MAAM,0CAAqC,KAAK;AACxD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;ALjDA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,OAAO,EACZ,YAAY,0DAA0D,EACtE,QAAQ,OAAO,EACf,SAAS,eAAe,6CAA6C,QAAQ,EAC7E,OAAO,qBAAqB,6BAA6B,MAAM,EAC/D,OAAO,CAAC,WAAW,YAAY;AAE9B,aAAW,EAAE,KAAK,WAAW,MAAM,QAAQ,KAAK,CAAC;AACnD,CAAC;AAEH,QACG,QAAQ,KAAK,EACb,YAAY,0BAA0B,EACtC,OAAO,qBAAqB,6BAA6B,MAAM,EAC/D,OAAO,yBAAyB,yBAAyB,QAAQ,EACjE,OAAO,UAAU;AAEpB,QACG,QAAQ,OAAO,EACf,YAAY,iCAAiC,EAC7C,OAAO,yBAAyB,yBAAyB,QAAQ,EACjE,OAAO,4BAA4B,oBAAoB,MAAM,EAC7D,OAAO,YAAY;AAEtB,QACG,QAAQ,SAAS,EACjB,YAAY,kCAAkC,EAC9C,OAAO,qBAAqB,iCAAiC,MAAM,EACnE,OAAO,4BAA4B,wBAAwB,MAAM,EACjE,OAAO,cAAc;AAExB,QAAQ,MAAM;","names":["segments","path","path","server","path","path","vue","path","fs","getFileRoute","path","path","fs","createServer"]}
1
+ {"version":3,"sources":["../src/scanner/index.ts","../src/parser/index.ts","../src/cli/index.ts","../src/cli/commands/dev.ts","../src/builder/vite-dev.ts","../src/cli/commands/build.ts","../src/builder/index.ts","../src/cli/commands/preview.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\nimport { SkillDirectory, SkillFile } from '../types/index.js'\n\nexport async function scanSkillsDirectory(sourceDir: string): Promise<SkillDirectory[]> {\n try {\n await fs.access(sourceDir)\n } catch {\n throw new Error(`Source directory not found: ${sourceDir}`)\n }\n\n const entries = await fs.readdir(sourceDir, { withFileTypes: true })\n const directories: SkillDirectory[] = []\n\n for (const entry of entries) {\n if (entry.isDirectory()) {\n const dirPath = path.join(sourceDir, entry.name)\n const skillDirectory = await scanDirectory(dirPath, entry.name)\n directories.push(skillDirectory)\n }\n }\n\n return directories\n}\n\nasync function scanDirectory(dirPath: string, name: string): Promise<SkillDirectory> {\n const entries = await fs.readdir(dirPath, { withFileTypes: true })\n const children: (SkillDirectory | SkillFile)[] = []\n let skillFile: SkillFile | undefined\n\n for (const entry of entries) {\n const entryPath = path.join(dirPath, entry.name)\n\n if (entry.isDirectory()) {\n const subDir = await scanDirectory(entryPath, entry.name)\n children.push(subDir)\n } else if (entry.isFile() && entry.name.endsWith('.md')) {\n const file = await parseMarkdownFile(entryPath, entry.name)\n \n if (entry.name === 'SKILL.md') {\n skillFile = file\n } else {\n children.push(file)\n }\n }\n }\n\n return {\n path: dirPath,\n name,\n children,\n skillFile\n }\n}\n\nasync function parseMarkdownFile(filePath: string, fileName: string): Promise<SkillFile> {\n const content = await fs.readFile(filePath, 'utf-8')\n const stats = await fs.stat(filePath)\n\n // Basic frontmatter extraction\n const frontmatterMatch = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---\\r?\\n/)\n const frontmatter: Record<string, any> = {}\n let markdownContent = content\n\n if (frontmatterMatch) {\n // Remove frontmatter from content\n markdownContent = content.slice(frontmatterMatch[0].length)\n \n // Parse frontmatter key-value pairs\n const fmLines = frontmatterMatch[1].split(/\\r?\\n/)\n for (const line of fmLines) {\n const colonIndex = line.indexOf(':')\n if (colonIndex > 0) {\n const key = line.slice(0, colonIndex).trim()\n const value = line.slice(colonIndex + 1).trim().replace(/^[\"']|[\"']$/g, '')\n if (key && value) {\n frontmatter[key] = value\n }\n }\n }\n }\n\n return {\n path: filePath,\n name: fileName,\n title: frontmatter.title || fileName.replace('.md', ''),\n description: frontmatter.description,\n content: markdownContent,\n frontmatter,\n lastModified: stats.mtime.getTime()\n }\n}\n\nexport async function watchSkillsDirectory(\n sourceDir: string, \n callback: (directories: SkillDirectory[]) => void\n) {\n const chokidar = await import('chokidar')\n \n const watcher = chokidar.watch(sourceDir, {\n ignored: /node_modules/,\n persistent: true,\n ignoreInitial: true\n })\n\n let debounceTimer: NodeJS.Timeout\n\n const handleChange = () => {\n clearTimeout(debounceTimer)\n debounceTimer = setTimeout(async () => {\n try {\n const directories = await scanSkillsDirectory(sourceDir)\n callback(directories)\n } catch (error) {\n console.error('Error rescanning source directory:', error)\n }\n }, 300)\n }\n\n watcher.on('add', handleChange)\n watcher.on('change', handleChange)\n watcher.on('unlink', handleChange)\n watcher.on('addDir', handleChange)\n watcher.on('unlinkDir', handleChange)\n\n return watcher\n}","import matter from 'gray-matter'\nimport MarkdownIt from 'markdown-it'\nimport { createHighlighter, Highlighter } from 'shiki'\nimport { SkillDirectory, SkillFile, SiteConfig, DocGenConfig, Navigation } from '../types/index.js'\n\nlet highlighter: Highlighter | null = null\n\nasync function getHighlighter() {\n if (!highlighter) {\n highlighter = await createHighlighter({\n themes: ['github-dark', 'github-light'],\n langs: ['javascript', 'typescript', 'bash', 'shell', 'json', 'html', 'css', 'vue', 'jsx', 'tsx', 'python', 'markdown', 'yaml', 'sql', 'go', 'rust', 'java', 'c', 'cpp']\n })\n }\n return highlighter\n}\n\nconst md = new MarkdownIt({\n html: true,\n linkify: true,\n typographer: true,\n highlight: function (str: string, lang: string) {\n // Synchronous fallback - actual highlighting done in enhanceFileContent\n return `<pre class=\"shiki-pending\" data-lang=\"${lang || 'text'}\"><code>${md.utils.escapeHtml(str)}</code></pre>`\n }\n})\n\nexport async function parseSkillsToConfig(\n directories: SkillDirectory[],\n siteConfig: SiteConfig\n): Promise<DocGenConfig> {\n const files: SkillFile[] = []\n const navigation = await generateNavigation(directories)\n\n // Collect all files for search indexing\n collectAllFiles(directories, files)\n\n // Enhance files with parsed content\n for (const file of files) {\n await enhanceFileContent(file)\n }\n\n return {\n siteConfig,\n navigation,\n files,\n directories\n }\n}\n\nfunction collectAllFiles(items: (SkillDirectory | SkillFile)[], files: SkillFile[]) {\n for (const item of items) {\n if ('content' in item) {\n // It's a SkillFile\n files.push(item)\n } else {\n // It's a SkillDirectory\n if (item.skillFile) {\n files.push(item.skillFile)\n }\n collectAllFiles(item.children, files)\n }\n }\n}\n\nasync function enhanceFileContent(file: SkillFile) {\n try {\n let content = file.content\n\n // Update title and description from frontmatter if available\n file.title = file.frontmatter.title || file.title\n file.description = file.frontmatter.description || file.description\n\n // Remove duplicate h1 if it matches frontmatter title\n if (file.frontmatter.title) {\n // Match first h1 heading in content (may have leading whitespace/newlines)\n const h1Match = content.match(/^\\s*#\\s+(.+)$/m)\n if (h1Match) {\n const h1Text = h1Match[1].trim()\n // If h1 matches title, remove it to avoid duplication\n if (h1Text === file.frontmatter.title) {\n content = content.replace(/^\\s*#\\s+.+\\n*/, '')\n }\n }\n }\n\n // Render markdown to HTML\n let html = md.render(content)\n \n // Apply syntax highlighting with shiki\n html = await highlightCodeBlocks(html)\n file.frontmatter.html = html\n\n // Extract headings for TOC\n const headings = extractHeadings(content)\n file.frontmatter.headings = headings\n\n } catch (error) {\n console.warn(`Failed to enhance content for ${file.path}:`, error)\n try {\n file.frontmatter.html = md.render(file.content)\n } catch (e) {\n console.error(`Failed to render markdown for ${file.path}:`, e)\n }\n }\n}\n\nasync function highlightCodeBlocks(html: string): Promise<string> {\n const hl = await getHighlighter()\n \n // Find all pending shiki code blocks and highlight them\n const codeBlockRegex = /<pre class=\"shiki-pending\" data-lang=\"([^\"]*)\"[^>]*><code>([^]*?)<\\/code><\\/pre>/g\n \n const matches = [...html.matchAll(codeBlockRegex)]\n \n for (const match of matches) {\n const [fullMatch, lang, escapedCode] = match\n // Unescape HTML entities\n const code = escapedCode\n .replace(/&lt;/g, '<')\n .replace(/&gt;/g, '>')\n .replace(/&amp;/g, '&')\n .replace(/&quot;/g, '\"')\n .replace(/&#39;/g, \"'\")\n \n try {\n const validLang = hl.getLoadedLanguages().includes(lang) ? lang : 'text'\n const highlighted = hl.codeToHtml(code, {\n lang: validLang,\n theme: 'github-dark'\n })\n html = html.replace(fullMatch, highlighted)\n } catch (e) {\n // Keep original if highlighting fails\n console.warn(`Failed to highlight ${lang}:`, e)\n }\n }\n \n return html\n}\n\nfunction extractHeadings(content: string) {\n const headings: Array<{ level: number; text: string; anchor: string }> = []\n const lines = content.split('\\n')\n\n for (const line of lines) {\n const match = line.match(/^(#{1,6})\\\\s+(.+)$/)\n if (match) {\n const level = match[1].length\n const text = match[2].trim()\n const anchor = text.toLowerCase()\n .replace(/[^\\\\w\\\\s-]/g, '')\n .replace(/\\\\s+/g, '-')\n .trim()\n\n headings.push({ level, text, anchor })\n }\n }\n\n return headings\n}\n\nasync function generateNavigation(directories: SkillDirectory[]): Promise<Navigation[]> {\n const navigation: Navigation[] = []\n\n for (const dir of directories) {\n const navItem: Navigation = {\n text: dir.skillFile?.title || formatDirName(dir.name),\n link: dir.skillFile ? getFileRoute(dir.skillFile) : undefined\n }\n\n if (dir.children.length > 0) {\n navItem.children = []\n \n for (const child of dir.children) {\n if ('content' in child) {\n // It's a file\n navItem.children.push({\n text: child.title || formatFileName(child.name),\n link: getFileRoute(child)\n })\n } else {\n // It's a subdirectory\n const subNav = await generateNavigation([child])\n navItem.children.push(...subNav)\n }\n }\n }\n\n navigation.push(navItem)\n }\n\n return navigation\n}\n\nfunction getFileRoute(file: SkillFile): string {\n // Import the utility function from client utils\n // For now, use inline implementation\n const filePath = file.path\n \n // Try common patterns\n const patterns = ['my-docs', 'docs', 'documentation', '.claude/skills']\n let relativePath = ''\n \n for (const pattern of patterns) {\n const index = filePath.indexOf(pattern)\n if (index !== -1) {\n relativePath = filePath.slice(index + pattern.length)\n break\n }\n }\n \n if (!relativePath) {\n // Fallback: use last 2 segments\n const segments = filePath.split('/').filter(Boolean)\n if (segments.length >= 2) {\n relativePath = '/' + segments.slice(-2).join('/')\n } else {\n return '/'\n }\n }\n \n const segments = relativePath.split('/').filter(Boolean)\n \n if (segments.length === 0) return '/'\n \n // Remove file extension\n const lastSegment = segments[segments.length - 1]\n if (lastSegment.endsWith('.md')) {\n segments[segments.length - 1] = lastSegment.slice(0, -3)\n }\n \n // SKILL.md and README.md should map to parent directory route\n const finalSegment = segments[segments.length - 1]\n if (finalSegment === 'SKILL' || finalSegment === 'README') {\n segments.pop()\n }\n \n return '/' + segments.join('/')\n}\n\nfunction formatDirName(name: string): string {\n return name.split('-').map(word => \n word.charAt(0).toUpperCase() + word.slice(1)\n ).join(' ')\n}\n\nfunction formatFileName(name: string): string {\n const baseName = name.replace('.md', '')\n return formatDirName(baseName)\n}\n\nexport { md as markdownRenderer }","#!/usr/bin/env node\n\nimport { Command } from 'commander'\nimport { devCommand } from './commands/dev.js'\nimport { buildCommand } from './commands/build.js'\nimport { previewCommand } from './commands/preview.js'\n\nconst program = new Command()\n\nprogram\n .name('docmk')\n .description('CLI tool for generating documentation from any directory')\n .version('1.0.0')\n .argument('[directory]', 'Source directory path (starts dev server)', './docs')\n .option('-p, --port <port>', 'Port to run dev server on', '3000')\n .action((directory, options) => {\n // Default action: start dev server\n devCommand({ dir: directory, port: options.port })\n })\n\nprogram\n .command('dev')\n .description('Start development server')\n .option('-p, --port <port>', 'Port to run dev server on', '3000')\n .option('-d, --dir <directory>', 'Source directory path', './docs')\n .action(devCommand)\n\nprogram\n .command('build')\n .description('Build static documentation site')\n .option('-d, --dir <directory>', 'Source directory path', './docs')\n .option('-o, --output <directory>', 'Output directory', 'dist')\n .action(buildCommand)\n\nprogram\n .command('preview')\n .description('Preview built documentation site')\n .option('-p, --port <port>', 'Port to run preview server on', '4173')\n .option('-o, --output <directory>', 'Built site directory', 'dist')\n .action(previewCommand)\n\nprogram.parse()","import path from 'path'\nimport { createViteDevServer } from '../../builder/vite-dev.js'\nimport { scanSkillsDirectory } from '../../scanner/index.js'\nimport { parseSkillsToConfig } from '../../parser/index.js'\n\ninterface DevOptions {\n port: string\n dir: string\n}\n\nexport async function devCommand(options: DevOptions) {\n console.log('šŸš€ Starting DocGen development server...')\n \n const sourceDir = path.resolve(process.cwd(), options.dir)\n const port = parseInt(options.port, 10)\n \n try {\n // Check if source directory exists\n console.log(`šŸ“ Scanning source directory: ${sourceDir}`)\n const directories = await scanSkillsDirectory(sourceDir)\n \n console.log(`āœ… Found ${directories.length} directories`)\n \n // Parse to config\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir: 'dist'\n })\n \n // Start Vite dev server\n const server = await createViteDevServer({\n port,\n skillsDir: sourceDir,\n config\n })\n \n console.log(`šŸŽ‰ Dev server running at http://localhost:${port}`)\n \n // Handle graceful shutdown\n process.on('SIGINT', async () => {\n console.log('\\\\nšŸ‘‹ Shutting down dev server...')\n await server.close()\n process.exit(0)\n })\n \n } catch (error) {\n console.error('āŒ Failed to start dev server:', error)\n process.exit(1)\n }\n}","import { createServer, ViteDevServer } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport { DocGenConfig } from '../types/index.js'\nimport { scanSkillsDirectory, watchSkillsDirectory } from '../scanner/index.js'\nimport { parseSkillsToConfig } from '../parser/index.js'\n\n// Get the package root directory (where src/client is located)\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst packageRoot = path.resolve(__dirname, '../..')\n\ninterface DevServerOptions {\n port: number\n skillsDir: string\n config: DocGenConfig\n}\n\nexport async function createViteDevServer(options: DevServerOptions): Promise<ViteDevServer> {\n let currentConfig = options.config\n\n const server = await createServer({\n root: path.resolve(packageRoot, 'src/client'),\n server: {\n port: options.port,\n host: 'localhost'\n },\n publicDir: false, // Disable public dir in dev mode\n plugins: [\n vue(),\n // Custom plugin to inject config and handle API routes\n {\n name: 'docgen-dev',\n configureServer(server) {\n // API endpoint for configuration\n server.middlewares.use('/api/config', (req, res, next) => {\n if (req.method === 'GET') {\n res.setHeader('Content-Type', 'application/json')\n res.end(JSON.stringify(currentConfig))\n } else {\n next()\n }\n })\n\n // SPA fallback - return index.html for all non-API routes\n return () => {\n server.middlewares.use((req, res, next) => {\n // Skip API routes and vite's own routes\n if (req.url?.startsWith('/api/') || req.url?.startsWith('/@') || req.url?.includes('.html')) {\n return next()\n }\n // For all other routes, serve index.html for SPA routing\n if (req.url && !req.url.includes('.')) {\n req.url = '/index.html'\n }\n next()\n })\n }\n },\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n // Inject lightweight config placeholder\n // Full config will be loaded via API to avoid HTML parsing issues\n const configScript = `\n <script>\n // Config will be loaded from /api/config\n globalThis.__DOCGEN_CONFIG__ = null;\n </script>\n `\n return html.replace('<head>', `<head>${configScript}`)\n }\n }\n }\n ],\n resolve: {\n alias: {\n '@': path.resolve(packageRoot, 'src/client')\n }\n },\n define: {\n __DOCGEN_CONFIG__: JSON.stringify(currentConfig)\n }\n })\n\n // Watch skills directory for changes\n const watcher = await watchSkillsDirectory(options.skillsDir, async (directories) => {\n console.log('šŸ“ Skills directory changed, updating configuration...')\n \n try {\n currentConfig = await parseSkillsToConfig(directories, currentConfig.siteConfig)\n \n // Notify all connected clients to reload\n server.ws.send({\n type: 'full-reload'\n })\n \n console.log('āœ… Configuration updated')\n } catch (error) {\n console.error('āŒ Failed to update configuration:', error)\n \n // Send error to clients\n server.ws.send({\n type: 'error',\n err: {\n message: `Failed to update configuration: ${error.message}`,\n stack: error.stack\n }\n })\n }\n })\n\n // Start the server\n await server.listen()\n\n // Extend server with cleanup method\n const originalClose = server.close.bind(server)\n server.close = async () => {\n await watcher?.close()\n return originalClose()\n }\n\n return server\n}\n\nexport async function createProductionBuild() {\n // This will be implemented in the builder\n}","import path from 'path'\nimport { buildSite } from '../../builder/index.js'\nimport { scanSkillsDirectory } from '../../scanner/index.js'\nimport { parseSkillsToConfig } from '../../parser/index.js'\n\ninterface BuildOptions {\n dir: string\n output: string\n}\n\nexport async function buildCommand(options: BuildOptions) {\n console.log('šŸ—ļø Building DocGen documentation site...')\n \n const sourceDir = path.resolve(process.cwd(), options.dir)\n const outputDir = path.resolve(process.cwd(), options.output)\n \n try {\n // Scan source directory\n console.log(`šŸ“ Scanning source directory: ${sourceDir}`)\n const directories = await scanSkillsDirectory(sourceDir)\n \n console.log(`āœ… Found ${directories.length} directories`)\n \n // Parse to config\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir\n })\n \n // Build site\n console.log(`šŸ“¦ Building to: ${outputDir}`)\n await buildSite({\n input: sourceDir,\n output: outputDir,\n mode: 'production'\n }, config)\n \n console.log('āœ… Build completed successfully!')\n console.log(`šŸ“‚ Built files are in: ${outputDir}`)\n \n } catch (error) {\n console.error('āŒ Build failed:', error)\n process.exit(1)\n }\n}","import { build } from 'vite'\nimport vue from '@vitejs/plugin-vue'\nimport path from 'path'\nimport { fileURLToPath } from 'url'\nimport fs from 'fs/promises'\nimport { DocGenConfig, BuildOptions } from '../types/index.js'\n\n// Get the package root directory\nconst __dirname = path.dirname(fileURLToPath(import.meta.url))\nconst packageRoot = path.resolve(__dirname, '../..')\n\nexport async function buildSite(options: BuildOptions, config: DocGenConfig) {\n console.log('šŸ—ļø Building documentation site...')\n\n // Ensure output directory exists\n await fs.mkdir(options.output, { recursive: true })\n\n // Write config to a temporary file for the build process\n const configPath = path.join(process.cwd(), 'temp-config.json')\n await fs.writeFile(configPath, JSON.stringify(config, null, 2))\n\n try {\n // Build the client application\n await build({\n root: path.resolve(packageRoot, 'src/client'),\n base: config.siteConfig.baseUrl,\n build: {\n outDir: options.output,\n emptyOutDir: true,\n rollupOptions: {\n input: {\n main: path.resolve(packageRoot, 'src/client/index.html')\n }\n }\n },\n plugins: [\n vue(),\n // Plugin to inject config during build\n {\n name: 'docgen-build',\n transformIndexHtml: {\n order: 'pre',\n handler(html) {\n // Encode config as base64 with proper UTF-8 handling\n const configJson = JSON.stringify(config)\n // Use encodeURIComponent to handle UTF-8 properly before base64\n const utf8Encoded = unescape(encodeURIComponent(configJson))\n const configBase64 = Buffer.from(utf8Encoded, 'binary').toString('base64')\n // Decode: atob -> decodeURIComponent(escape()) to restore UTF-8\n const configScript = `<script>globalThis.__DOCGEN_CONFIG__=JSON.parse(decodeURIComponent(escape(atob(\"${configBase64}\"))));</script>`\n return html.replace('</head>', `${configScript}\\n</head>`)\n }\n }\n }\n ],\n resolve: {\n alias: {\n '@': path.resolve(packageRoot, 'src/client')\n }\n },\n define: {\n __DOCGEN_CONFIG__: JSON.stringify(config)\n }\n })\n \n // Generate additional static files\n await generateSitemap(options.output, config)\n await generateRobotsTxt(options.output, config)\n await copyAssets(options.output)\n \n console.log('āœ… Build completed successfully!')\n \n } finally {\n // Clean up temporary config file\n try {\n await fs.unlink(configPath)\n } catch {\n // Ignore if file doesn't exist\n }\n }\n}\n\nasync function generateSitemap(outputDir: string, config: DocGenConfig) {\n console.log('šŸ“„ Generating sitemap...')\n \n const baseUrl = config.siteConfig.baseUrl.replace(/\\/$/, '')\n const urls: string[] = []\n \n // Add home page\n urls.push(`${baseUrl}/`)\n \n // Add all skill pages\n for (const file of config.files) {\n const route = getFileRoute(file.path, config.siteConfig.skillsDir)\n if (route !== '/') {\n urls.push(`${baseUrl}${route}`)\n }\n }\n \n const sitemap = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n${urls.map(url => ` <url>\n <loc>${url}</loc>\n <lastmod>${new Date().toISOString().split('T')[0]}</lastmod>\n <changefreq>weekly</changefreq>\n <priority>0.8</priority>\n </url>`).join('\\\\n')}\n</urlset>`\n \n await fs.writeFile(path.join(outputDir, 'sitemap.xml'), sitemap)\n}\n\nasync function generateRobotsTxt(outputDir: string, config: DocGenConfig) {\n console.log('šŸ¤– Generating robots.txt...')\n \n const baseUrl = config.siteConfig.baseUrl.replace(/\\/$/, '')\n const robotsTxt = `User-agent: *\nAllow: /\n\nSitemap: ${baseUrl}/sitemap.xml`\n \n await fs.writeFile(path.join(outputDir, 'robots.txt'), robotsTxt)\n}\n\nasync function copyAssets(outputDir: string) {\n console.log('šŸ“ Copying static assets...')\n \n // Create a simple favicon if it doesn't exist\n const faviconPath = path.join(outputDir, 'favicon.ico')\n \n try {\n await fs.access(faviconPath)\n } catch {\n // Create a simple SVG favicon\n const faviconSvg = `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\">\n <rect width=\"32\" height=\"32\" rx=\"4\" fill=\"#3182ce\"/>\n <text x=\"16\" y=\"22\" text-anchor=\"middle\" fill=\"white\" font-family=\"system-ui\" font-size=\"18\" font-weight=\"bold\">D</text>\n</svg>`\n \n await fs.writeFile(path.join(outputDir, 'favicon.svg'), faviconSvg)\n }\n}\n\nfunction getFileRoute(filePath: string, baseDir: string): string {\n // Normalize paths for comparison\n const normalizedFilePath = path.normalize(filePath)\n const normalizedBaseDir = path.normalize(baseDir)\n \n // Check if file is within base directory\n if (!normalizedFilePath.startsWith(normalizedBaseDir)) {\n return '/'\n }\n \n // Get relative path from base directory\n const relativePath = normalizedFilePath.slice(normalizedBaseDir.length)\n const segments = relativePath.split(path.sep).filter(Boolean)\n \n if (segments.length === 0) return '/'\n \n const lastSegment = segments[segments.length - 1]\n if (lastSegment.endsWith('.md')) {\n segments[segments.length - 1] = lastSegment.slice(0, -3)\n }\n \n // SKILL.md and README.md should map to parent directory route\n const finalSegment = segments[segments.length - 1]\n if (finalSegment === 'SKILL' || finalSegment === 'README') {\n segments.pop()\n }\n\n return '/' + segments.join('/')\n}\n\nexport async function buildForProduction(sourceDir: string, outputDir: string): Promise<DocGenConfig> {\n const { scanSkillsDirectory } = await import('../scanner/index.js')\n const { parseSkillsToConfig } = await import('../parser/index.js')\n \n const directories = await scanSkillsDirectory(sourceDir)\n const config = await parseSkillsToConfig(directories, {\n title: 'Documentation',\n description: 'Documentation generated from source directory',\n baseUrl: '/',\n skillsDir: sourceDir,\n outputDir\n })\n \n await buildSite({\n input: sourceDir,\n output: outputDir,\n mode: 'production'\n }, config)\n \n return config\n}","import path from 'path'\nimport fs from 'fs/promises'\nimport sirv from 'sirv'\nimport { createServer } from 'http'\n\ninterface PreviewOptions {\n port: string\n output: string\n}\n\nexport async function previewCommand(options: PreviewOptions) {\n console.log('šŸ‘€ Starting DocGen preview server...')\n \n const outputDir = path.resolve(process.cwd(), options.output)\n const port = parseInt(options.port, 10)\n \n try {\n // Check if build directory exists\n try {\n await fs.access(outputDir)\n } catch {\n console.error(`āŒ Build directory not found: ${outputDir}`)\n console.log('šŸ’” Run \"docgen build\" first to generate the static site')\n process.exit(1)\n }\n \n // Create static file server\n const serve = sirv(outputDir, {\n single: true, // SPA mode\n dev: false,\n setHeaders: (res, pathname) => {\n if (pathname.endsWith('.html') || pathname === '/') {\n res.setHeader('Content-Type', 'text/html; charset=utf-8')\n }\n }\n })\n \n const server = createServer(serve)\n \n server.listen(port, () => {\n console.log(`šŸŽ‰ Preview server running at http://localhost:${port}`)\n console.log(`šŸ“‚ Serving files from: ${outputDir}`)\n })\n \n // Handle graceful shutdown\n process.on('SIGINT', () => {\n console.log('\\\\nšŸ‘‹ Shutting down preview server...')\n server.close(() => {\n process.exit(0)\n })\n })\n \n } catch (error) {\n console.error('āŒ Failed to start preview server:', error)\n process.exit(1)\n }\n}"],"mappings":"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","names":["segments","path","path","server","path","path","vue","path","fileURLToPath","fs","__dirname","packageRoot","getFileRoute","path","path","fs","createServer"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docmk",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A CLI tool for scanning directories and generating static documentation websites",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -1,30 +1,35 @@
1
1
  import { build } from 'vite'
2
2
  import vue from '@vitejs/plugin-vue'
3
3
  import path from 'path'
4
+ import { fileURLToPath } from 'url'
4
5
  import fs from 'fs/promises'
5
6
  import { DocGenConfig, BuildOptions } from '../types/index.js'
6
7
 
8
+ // Get the package root directory
9
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
10
+ const packageRoot = path.resolve(__dirname, '../..')
11
+
7
12
  export async function buildSite(options: BuildOptions, config: DocGenConfig) {
8
13
  console.log('šŸ—ļø Building documentation site...')
9
-
14
+
10
15
  // Ensure output directory exists
11
16
  await fs.mkdir(options.output, { recursive: true })
12
-
17
+
13
18
  // Write config to a temporary file for the build process
14
19
  const configPath = path.join(process.cwd(), 'temp-config.json')
15
20
  await fs.writeFile(configPath, JSON.stringify(config, null, 2))
16
-
21
+
17
22
  try {
18
23
  // Build the client application
19
24
  await build({
20
- root: path.resolve(process.cwd(), 'src/client'),
25
+ root: path.resolve(packageRoot, 'src/client'),
21
26
  base: config.siteConfig.baseUrl,
22
27
  build: {
23
28
  outDir: options.output,
24
29
  emptyOutDir: true,
25
30
  rollupOptions: {
26
31
  input: {
27
- main: path.resolve(process.cwd(), 'src/client/index.html')
32
+ main: path.resolve(packageRoot, 'src/client/index.html')
28
33
  }
29
34
  }
30
35
  },
@@ -50,7 +55,7 @@ export async function buildSite(options: BuildOptions, config: DocGenConfig) {
50
55
  ],
51
56
  resolve: {
52
57
  alias: {
53
- '@': path.resolve(process.cwd(), 'src/client')
58
+ '@': path.resolve(packageRoot, 'src/client')
54
59
  }
55
60
  },
56
61
  define: {
@@ -1,10 +1,15 @@
1
1
  import { createServer, ViteDevServer } from 'vite'
2
2
  import vue from '@vitejs/plugin-vue'
3
3
  import path from 'path'
4
+ import { fileURLToPath } from 'url'
4
5
  import { DocGenConfig } from '../types/index.js'
5
6
  import { scanSkillsDirectory, watchSkillsDirectory } from '../scanner/index.js'
6
7
  import { parseSkillsToConfig } from '../parser/index.js'
7
8
 
9
+ // Get the package root directory (where src/client is located)
10
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
11
+ const packageRoot = path.resolve(__dirname, '../..')
12
+
8
13
  interface DevServerOptions {
9
14
  port: number
10
15
  skillsDir: string
@@ -15,7 +20,7 @@ export async function createViteDevServer(options: DevServerOptions): Promise<Vi
15
20
  let currentConfig = options.config
16
21
 
17
22
  const server = await createServer({
18
- root: path.resolve(process.cwd(), 'src/client'),
23
+ root: path.resolve(packageRoot, 'src/client'),
19
24
  server: {
20
25
  port: options.port,
21
26
  host: 'localhost'
@@ -70,7 +75,7 @@ export async function createViteDevServer(options: DevServerOptions): Promise<Vi
70
75
  ],
71
76
  resolve: {
72
77
  alias: {
73
- '@': path.resolve(process.cwd(), 'src/client')
78
+ '@': path.resolve(packageRoot, 'src/client')
74
79
  }
75
80
  },
76
81
  define: {