@oddessentials/odd-docs 2.0.1 → 2.0.2

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/cli/index.js CHANGED
@@ -1,8 +1,6 @@
1
1
  // src/cli/index.ts
2
2
  import { Command } from "commander";
3
- import { readFileSync } from "fs";
4
- import { dirname, join as join5 } from "path";
5
- import { fileURLToPath } from "url";
3
+ import { createRequire } from "module";
6
4
 
7
5
  // src/cli/commands/generate.ts
8
6
  import { writeFile, mkdir } from "fs/promises";
@@ -1438,8 +1436,8 @@ async function serve(repoPath, options = {}) {
1438
1436
  }
1439
1437
 
1440
1438
  // src/cli/index.ts
1441
- var __dirname = dirname(fileURLToPath(import.meta.url));
1442
- var packageJson = JSON.parse(readFileSync(join5(__dirname, "../../package.json"), "utf-8"));
1439
+ var require2 = createRequire(import.meta.url);
1440
+ var packageJson = require2("../../package.json");
1443
1441
  var program = new Command();
1444
1442
  program.name("odd-docs").description("MCP-native documentation generator").version(packageJson.version);
1445
1443
  program.command("generate").description("Generate documentation for an MCP repo").argument("<repo-path>", "Path to the repository").option("-f, --format <format>", "Output format: md, html, or both", "md").option("-o, --output <dir>", "Output directory").option("--introspect <url>", "MCP server URL for live introspection").action(async (repoPath, options) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/generate.ts","../../src/core/parser/manifestParser.ts","../../src/core/ir/builder.ts","../../src/core/parser/schemaParser.ts","../../src/core/renderer/markdownRenderer.ts","../../src/core/renderer/htmlRenderer.ts","../../src/cli/commands/validate.ts","../../src/core/capabilities.ts","../../src/core/ir/validator.ts","../../src/cli/commands/serve.ts","../../src/server/index.ts","../../src/server/fileServer.ts","../../src/server/livereload.ts","../../src/server/api.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { generate } from './commands/generate.js';\nimport { validate } from './commands/validate.js';\nimport { serve } from './commands/serve.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJson = JSON.parse(readFileSync(join(__dirname, '../../package.json'), 'utf-8'));\n\nconst program = new Command();\n\nprogram\n .name('odd-docs')\n .description('MCP-native documentation generator')\n .version(packageJson.version);\n\nprogram\n .command('generate')\n .description('Generate documentation for an MCP repo')\n .argument('<repo-path>', 'Path to the repository')\n .option('-f, --format <format>', 'Output format: md, html, or both', 'md')\n .option('-o, --output <dir>', 'Output directory')\n .option('--introspect <url>', 'MCP server URL for live introspection')\n .action(async (repoPath: string, options) => {\n try {\n await generate(repoPath, {\n format: options.format,\n output: options.output,\n introspect: options.introspect,\n });\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('validate')\n .description('Validate documentation inputs for an MCP repo')\n .argument('<repo-path>', 'Path to the repository')\n .option('-s, --strict', 'Fail on unknown safety-affecting capabilities')\n .action(async (repoPath: string, options) => {\n try {\n const valid = await validate(repoPath, { strict: options.strict });\n process.exit(valid ? 0 : 1);\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('serve')\n .description('Start a local dev server for generated documentation')\n .argument('<repo-path>', 'Path to the repository')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('-H, --host <host>', 'Host to bind (default: localhost for safety)', 'localhost')\n .option('-o, --output <dir>', 'Documentation output directory')\n .option('--no-watch', 'Disable file watching')\n .option('--watch-mode <mode>', 'Watch mode: auto or poll (use poll for Docker/NFS)', 'auto')\n .option('--reload <mode>', 'Reload mechanism: ws, sse, poll, none', 'ws')\n .option('--no-open', 'Do not open browser on start')\n .option('--introspect <target>', 'MCP target: http://host:port or stdio:<cmd>')\n .option('--enable-mutations', 'Enable mutation API endpoints (requires token)')\n .option('--mutation-token <token>', 'Token for mutation endpoints (or ODD_DOCS_MUTATION_TOKEN)')\n .action(async (repoPath: string, options) => {\n try {\n await serve(repoPath, {\n port: parseInt(options.port, 10),\n host: options.host,\n output: options.output,\n watch: options.watch,\n watchMode: options.watchMode,\n reload: options.reload,\n open: options.open,\n introspect: options.introspect,\n enableMutations: options.enableMutations,\n mutationToken: options.mutationToken,\n });\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import { writeFile, mkdir } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { parseManifest } from '../../core/parser/manifestParser.js';\nimport { buildDocIR } from '../../core/ir/builder.js';\nimport { renderMarkdown } from '../../core/renderer/markdownRenderer.js';\nimport { renderHTML } from '../../core/renderer/htmlRenderer.js';\n\nexport interface GenerateOptions {\n format?: 'md' | 'html' | 'both';\n output?: string;\n introspect?: string;\n}\n\nexport async function generate(repoPath: string, options: GenerateOptions = {}): Promise<void> {\n const absPath = resolve(repoPath);\n const format = options.format ?? 'md';\n const outputDir = options.output ? resolve(options.output) : join(absPath, 'docs', 'generated');\n\n console.log(`Generating documentation for: ${absPath}`);\n\n // Parse manifest\n const manifestResult = await parseManifest(absPath);\n console.log(` Entity: ${manifestResult.entity.id}@${manifestResult.entity.version}`);\n\n // Build Doc IR\n const ir = buildDocIR(manifestResult);\n console.log(` Determinism key: ${ir.determinismKey}`);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Render formats\n if (format === 'md' || format === 'both') {\n const markdown = renderMarkdown(ir);\n const mdPath = join(outputDir, `${ir.entity.id}.md`);\n await writeFile(mdPath, markdown, 'utf-8');\n console.log(` ✓ Markdown: ${mdPath}`);\n }\n\n if (format === 'html' || format === 'both') {\n const html = renderHTML(ir);\n const htmlPath = join(outputDir, `${ir.entity.id}.html`);\n await writeFile(htmlPath, html, 'utf-8');\n console.log(` ✓ HTML: ${htmlPath}`);\n }\n\n // Write IR for debugging/caching\n const irPath = join(outputDir, `${ir.entity.id}.ir.json`);\n await writeFile(irPath, JSON.stringify(ir, null, 2), 'utf-8');\n console.log(` ✓ Doc IR: ${irPath}`);\n\n console.log('Done!');\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { DocIR, Capability, SchemaSection } from '../ir/types.js';\n\ninterface ToolManifest {\n tool_id: string;\n version: string;\n description?: string;\n execution_mode?: 'IN_PROCESS' | 'RUNNER';\n parameters?: Record<string, unknown>;\n capabilities?: {\n network?: string[];\n filesystem?: string[];\n secrets?: string[];\n };\n timeout_ms?: number;\n resource_limits?: {\n memory_mb?: number;\n cpu_cores?: number;\n };\n deprecation?: {\n deprecated_at: string;\n sunset_date: string;\n migration_url?: string;\n };\n}\n\nexport interface ManifestParseResult {\n entity: DocIR['entity'];\n inputs: SchemaSection;\n constraints?: DocIR['constraints'];\n lifecycle?: DocIR['lifecycle'];\n}\n\n/**\n * Parse an MCP tool manifest file into partial Doc IR\n */\nexport async function parseManifest(repoPath: string): Promise<ManifestParseResult> {\n const manifestPath = join(repoPath, 'manifest.json');\n\n let content: string;\n try {\n content = await readFile(manifestPath, 'utf-8');\n } catch {\n throw new Error(`Manifest not found: ${manifestPath}`);\n }\n\n let manifest: ToolManifest;\n try {\n manifest = JSON.parse(content) as ToolManifest;\n } catch {\n throw new Error(`Invalid JSON in manifest: ${manifestPath}`);\n }\n\n // Validate required fields\n if (!manifest.tool_id) {\n throw new Error('Manifest missing required field: tool_id');\n }\n if (!manifest.version) {\n throw new Error('Manifest missing required field: version');\n }\n\n // Build capabilities array\n const capabilities: Capability[] = [];\n if (manifest.capabilities) {\n for (const [type, values] of Object.entries(manifest.capabilities)) {\n if (Array.isArray(values) && values.length > 0) {\n capabilities.push({ type, values, provenance: 'manifest' });\n }\n }\n }\n\n const result: ManifestParseResult = {\n entity: {\n type: 'tool',\n id: manifest.tool_id,\n version: manifest.version,\n description: manifest.description,\n },\n inputs: {\n schema: manifest.parameters,\n provenance: 'manifest',\n },\n };\n\n // Add constraints if present\n if (capabilities.length > 0 || manifest.timeout_ms || manifest.resource_limits) {\n result.constraints = {\n capabilities: capabilities.length > 0 ? capabilities : undefined,\n timeoutMs: manifest.timeout_ms,\n resourceLimits: manifest.resource_limits\n ? {\n memoryMb: manifest.resource_limits.memory_mb,\n cpuCores: manifest.resource_limits.cpu_cores,\n }\n : undefined,\n };\n }\n\n // Add lifecycle if deprecation present\n if (manifest.deprecation) {\n result.lifecycle = {\n version: manifest.version,\n deprecation: {\n deprecatedAt: manifest.deprecation.deprecated_at,\n sunsetDate: manifest.deprecation.sunset_date,\n migrationUrl: manifest.deprecation.migration_url,\n },\n };\n }\n\n return result;\n}\n","import { createHash } from 'node:crypto';\nimport type { DocIR } from './types.js';\nimport { enrichSchemaSection } from '../parser/schemaParser.js';\nimport type { ManifestParseResult } from '../parser/manifestParser.js';\n\n/**\n * Build a complete Doc IR from parsed sources\n */\nexport function buildDocIR(manifest: ManifestParseResult): DocIR {\n const enrichedInputs = enrichSchemaSection(manifest.inputs);\n\n const ir: DocIR = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n determinismKey: '', // Computed below\n entity: manifest.entity,\n inputs: enrichedInputs,\n constraints: manifest.constraints,\n lifecycle: manifest.lifecycle,\n provenance: {\n entity: 'manifest',\n inputs: 'manifest',\n },\n };\n\n // Compute determinism key\n ir.determinismKey = computeDeterminismKey(ir);\n\n return ir;\n}\n\n/**\n * Compute SHA-256 determinism key for caching and diffing\n */\nexport function computeDeterminismKey(ir: Omit<DocIR, 'determinismKey' | 'generatedAt'>): string {\n const canonical = JSON.stringify({\n entity: ir.entity,\n inputs: ir.inputs,\n constraints: ir.constraints,\n lifecycle: ir.lifecycle,\n });\n\n const hash = createHash('sha256').update(canonical).digest('hex');\n return `sha256:${hash}`;\n}\n","import type { Parameter, SchemaSection } from '../ir/types.js';\n\ninterface JSONSchema {\n type?: string;\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n default?: unknown;\n enum?: unknown[];\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n items?: JSONSchema;\n $ref?: string;\n}\n\n/**\n * Parse JSON Schema into a list of parameters for documentation\n */\nexport function parseSchema(schema: Record<string, unknown> | undefined): Parameter[] {\n if (!schema) return [];\n\n const jsonSchema = schema as JSONSchema;\n const parameters: Parameter[] = [];\n const required = new Set(jsonSchema.required ?? []);\n\n if (jsonSchema.properties) {\n for (const [name, propSchema] of Object.entries(jsonSchema.properties)) {\n parameters.push(parseProperty(name, propSchema, required.has(name)));\n }\n }\n\n return parameters;\n}\n\nfunction parseProperty(name: string, schema: JSONSchema, isRequired: boolean): Parameter {\n const param: Parameter = {\n name,\n type: resolveType(schema),\n required: isRequired,\n };\n\n if (schema.description) {\n param.description = schema.description;\n }\n\n if (schema.default !== undefined) {\n param.default = schema.default;\n }\n\n if (schema.enum) {\n param.enum = schema.enum;\n }\n\n // Build constraints string\n const constraints = buildConstraints(schema);\n if (constraints) {\n param.constraints = constraints;\n }\n\n return param;\n}\n\nfunction resolveType(schema: JSONSchema): string {\n if (schema.$ref) {\n // Extract type name from $ref\n const refParts = schema.$ref.split('/');\n return refParts[refParts.length - 1];\n }\n\n if (schema.enum) {\n return 'enum';\n }\n\n if (schema.type === 'array' && schema.items) {\n return `${resolveType(schema.items)}[]`;\n }\n\n return schema.type ?? 'unknown';\n}\n\nfunction buildConstraints(schema: JSONSchema): string | undefined {\n const parts: string[] = [];\n\n if (schema.minimum !== undefined) {\n parts.push(`min: ${schema.minimum}`);\n }\n if (schema.maximum !== undefined) {\n parts.push(`max: ${schema.maximum}`);\n }\n if (schema.minLength !== undefined) {\n parts.push(`minLength: ${schema.minLength}`);\n }\n if (schema.maxLength !== undefined) {\n parts.push(`maxLength: ${schema.maxLength}`);\n }\n if (schema.pattern) {\n parts.push(`pattern: ${schema.pattern}`);\n }\n\n return parts.length > 0 ? parts.join(', ') : undefined;\n}\n\n/**\n * Enrich a SchemaSection with parsed parameters\n */\nexport function enrichSchemaSection(section: SchemaSection): SchemaSection {\n return {\n ...section,\n parameters: parseSchema(section.schema),\n };\n}\n","import type { DocIR, Parameter, ProvenanceSource } from '../ir/types.js';\n\n/**\n * Render Doc IR to Markdown\n */\nexport function renderMarkdown(ir: DocIR): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${ir.entity.id}`);\n lines.push('');\n lines.push(`**Version:** ${ir.entity.version} `);\n lines.push(`**Type:** ${ir.entity.type} `);\n if (ir.entity.description) {\n lines.push('');\n lines.push(ir.entity.description);\n }\n lines.push('');\n\n // Overview\n if (ir.overview) {\n lines.push('## Overview');\n lines.push('');\n if (ir.overview.intent) {\n lines.push(`**Intent:** ${ir.overview.intent}`);\n lines.push('');\n }\n if (ir.overview.useCases?.length) {\n lines.push('### Use Cases');\n lines.push('');\n for (const useCase of ir.overview.useCases) {\n lines.push(`- ${useCase}`);\n }\n lines.push('');\n }\n if (ir.overview.sideEffects?.length) {\n lines.push('### Side Effects');\n lines.push('');\n for (const effect of ir.overview.sideEffects) {\n lines.push(\n `- **${effect.type}**: ${effect.description} ${provenanceBadge(effect.provenance)}`\n );\n }\n lines.push('');\n }\n }\n\n // Inputs\n if (ir.inputs?.parameters?.length) {\n lines.push('## Inputs');\n lines.push('');\n lines.push(provenanceBadge(ir.inputs.provenance));\n lines.push('');\n lines.push(renderParameterTable(ir.inputs.parameters));\n lines.push('');\n }\n\n // Outputs\n if (ir.outputs?.parameters?.length) {\n lines.push('## Outputs');\n lines.push('');\n lines.push(provenanceBadge(ir.outputs.provenance));\n lines.push('');\n lines.push(renderParameterTable(ir.outputs.parameters));\n lines.push('');\n }\n\n // Constraints\n if (ir.constraints) {\n lines.push('## Constraints');\n lines.push('');\n if (ir.constraints.capabilities?.length) {\n lines.push('### Capabilities');\n lines.push('');\n for (const cap of ir.constraints.capabilities) {\n const values = cap.values?.join(', ') ?? 'enabled';\n lines.push(`- **${cap.type}**: ${values} ${provenanceBadge(cap.provenance)}`);\n }\n lines.push('');\n }\n if (ir.constraints.timeoutMs) {\n lines.push(`**Timeout:** ${ir.constraints.timeoutMs}ms`);\n lines.push('');\n }\n if (ir.constraints.resourceLimits) {\n lines.push('### Resource Limits');\n lines.push('');\n if (ir.constraints.resourceLimits.memoryMb) {\n lines.push(`- Memory: ${ir.constraints.resourceLimits.memoryMb} MB`);\n }\n if (ir.constraints.resourceLimits.cpuCores) {\n lines.push(`- CPU: ${ir.constraints.resourceLimits.cpuCores} cores`);\n }\n lines.push('');\n }\n }\n\n // Errors\n if (ir.errors?.length) {\n lines.push('## Errors');\n lines.push('');\n lines.push('| Code | Description | Recovery |');\n lines.push('|------|-------------|----------|');\n for (const err of ir.errors) {\n lines.push(`| \\`${err.code}\\` | ${err.description ?? ''} | ${err.recovery ?? ''} |`);\n }\n lines.push('');\n }\n\n // Lifecycle\n if (ir.lifecycle?.deprecation) {\n lines.push('## Lifecycle');\n lines.push('');\n lines.push('> [!WARNING]');\n lines.push(`> This tool is deprecated as of ${ir.lifecycle.deprecation.deprecatedAt}.`);\n lines.push(`> Sunset date: ${ir.lifecycle.deprecation.sunsetDate}`);\n if (ir.lifecycle.deprecation.migrationUrl) {\n lines.push(`> Migration guide: ${ir.lifecycle.deprecation.migrationUrl}`);\n }\n lines.push('');\n }\n\n // Examples\n if (ir.narrative?.examples?.length) {\n lines.push('## Examples');\n lines.push('');\n for (const example of ir.narrative.examples) {\n if (example.title) {\n lines.push(`### ${example.title}`);\n lines.push('');\n }\n if (example.description) {\n lines.push(example.description);\n lines.push('');\n }\n if (example.input) {\n lines.push('**Input:**');\n lines.push('```json');\n lines.push(JSON.stringify(example.input, null, 2));\n lines.push('```');\n lines.push('');\n }\n if (example.output) {\n lines.push('**Output:**');\n lines.push('```json');\n lines.push(JSON.stringify(example.output, null, 2));\n lines.push('```');\n lines.push('');\n }\n }\n }\n\n // Notes\n if (ir.narrative?.notes?.length) {\n lines.push('## Notes');\n lines.push('');\n lines.push('*[author notes]*');\n lines.push('');\n for (const note of ir.narrative.notes) {\n lines.push(note);\n lines.push('');\n }\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push(`*Generated at ${ir.generatedAt}* `);\n lines.push(`*Determinism key: \\`${ir.determinismKey}\\`*`);\n\n return lines.join('\\n');\n}\n\nfunction renderParameterTable(params: Parameter[]): string {\n const lines: string[] = [];\n lines.push('| Name | Type | Required | Default | Description |');\n lines.push('|------|------|----------|---------|-------------|');\n\n for (const param of params) {\n const required = param.required ? '✓' : '';\n const defaultVal = param.default !== undefined ? `\\`${JSON.stringify(param.default)}\\`` : '';\n const desc = param.description ?? '';\n lines.push(`| \\`${param.name}\\` | \\`${param.type}\\` | ${required} | ${defaultVal} | ${desc} |`);\n }\n\n return lines.join('\\n');\n}\n\nfunction provenanceBadge(source?: ProvenanceSource): string {\n if (!source) return '';\n const badges: Record<ProvenanceSource, string> = {\n introspection: '`[from introspection]`',\n manifest: '`[from schema]`',\n overlay: '`[from overlay]`',\n narrative: '`[author notes]`',\n };\n return badges[source] ?? '';\n}\n","import { marked } from 'marked';\nimport type { DocIR } from '../ir/types.js';\nimport { renderMarkdown } from './markdownRenderer.js';\n\n/**\n * Render Doc IR to static HTML\n */\nexport function renderHTML(ir: DocIR): string {\n // First render to markdown, then convert to HTML\n const markdown = renderMarkdown(ir);\n const htmlContent = marked.parse(markdown) as string;\n\n return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"light\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta name=\"description\" content=\"${escapeHtml(ir.entity.description ?? `Documentation for ${ir.entity.id}`)}\">\n <title>${escapeHtml(ir.entity.id)} - odd-docs</title>\n <style>\n${getThemeStyles()}\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <nav class=\"breadcrumb\">\n <a href=\"index.html\">Home</a> / <span>${escapeHtml(ir.entity.id)}</span>\n </nav>\n </header>\n <main class=\"content\">\n${htmlContent}\n </main>\n <footer>\n <p class=\"meta\">\n Generated by <a href=\"https://github.com/oddessentials/odd-docs\">odd-docs</a> at ${ir.generatedAt}\n </p>\n <p class=\"determinism\">\n <code>${ir.determinismKey}</code>\n </p>\n </footer>\n </div>\n <script>\n${getThemeScript()}\n </script>\n</body>\n</html>`;\n}\n\n/**\n * Generate index page for multiple docs\n */\nexport function renderIndexHTML(docs: DocIR[]): string {\n const items = docs\n .map(\n (ir) => `\n <li>\n <a href=\"${ir.entity.id}.html\">\n <strong>${escapeHtml(ir.entity.id)}</strong>\n <span class=\"version\">v${ir.entity.version}</span>\n </a>\n <p>${escapeHtml(ir.entity.description ?? '')}</p>\n </li>`\n )\n .join('\\n');\n\n return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"light\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Documentation - odd-docs</title>\n <style>\n${getThemeStyles()}\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <h1>Documentation</h1>\n </header>\n <main class=\"content\">\n <ul class=\"doc-list\">\n${items}\n </ul>\n </main>\n <footer>\n <p class=\"meta\">Generated by <a href=\"https://github.com/oddessentials/odd-docs\">odd-docs</a></p>\n </footer>\n </div>\n <script>\n${getThemeScript()}\n </script>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\nfunction getThemeStyles(): string {\n return `\n /* CSS Variables for theming */\n :root {\n /* Colors - neutral palette */\n --color-bg: #ffffff;\n --color-bg-secondary: #f8f9fa;\n --color-text: #1a1a2e;\n --color-text-muted: #6c757d;\n --color-border: #dee2e6;\n --color-link: #0066cc;\n --color-link-hover: #004499;\n --color-accent: #0066cc;\n --color-success: #28a745;\n --color-warning: #ffc107;\n --color-error: #dc3545;\n \n /* Typography */\n --font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n --font-mono: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n --font-size-base: 16px;\n --line-height: 1.6;\n \n /* Spacing */\n --space-xs: 0.25rem;\n --space-sm: 0.5rem;\n --space-md: 1rem;\n --space-lg: 1.5rem;\n --space-xl: 2rem;\n \n /* Layout */\n --max-width: 800px;\n --border-radius: 4px;\n }\n \n [data-theme=\"dark\"] {\n --color-bg: #1a1a2e;\n --color-bg-secondary: #16213e;\n --color-text: #e8e8e8;\n --color-text-muted: #a0a0a0;\n --color-border: #3a3a5e;\n --color-link: #66b3ff;\n --color-link-hover: #99ccff;\n }\n \n /* Reset */\n *, *::before, *::after {\n box-sizing: border-box;\n }\n \n body {\n margin: 0;\n padding: 0;\n font-family: var(--font-sans);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text);\n background: var(--color-bg);\n }\n \n /* Container */\n .container {\n max-width: var(--max-width);\n margin: 0 auto;\n padding: var(--space-lg);\n }\n \n /* Typography */\n h1, h2, h3, h4, h5, h6 {\n margin-top: var(--space-xl);\n margin-bottom: var(--space-md);\n line-height: 1.3;\n }\n \n h1 { font-size: 2rem; }\n h2 { font-size: 1.5rem; border-bottom: 1px solid var(--color-border); padding-bottom: var(--space-sm); }\n h3 { font-size: 1.25rem; }\n \n p { margin: var(--space-md) 0; }\n \n a {\n color: var(--color-link);\n text-decoration: none;\n }\n \n a:hover {\n color: var(--color-link-hover);\n text-decoration: underline;\n }\n \n /* Code */\n code {\n font-family: var(--font-mono);\n font-size: 0.9em;\n background: var(--color-bg-secondary);\n padding: var(--space-xs) var(--space-sm);\n border-radius: var(--border-radius);\n }\n \n pre {\n background: var(--color-bg-secondary);\n padding: var(--space-md);\n border-radius: var(--border-radius);\n overflow-x: auto;\n }\n \n pre code {\n background: none;\n padding: 0;\n }\n \n /* Tables */\n table {\n width: 100%;\n border-collapse: collapse;\n margin: var(--space-md) 0;\n }\n \n th, td {\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n text-align: left;\n }\n \n th {\n background: var(--color-bg-secondary);\n font-weight: 600;\n }\n \n /* Provenance badges */\n code[class*=\"from\"] {\n font-size: 0.75em;\n color: var(--color-text-muted);\n background: transparent;\n }\n \n /* Blockquotes (for warnings/notes) */\n blockquote {\n margin: var(--space-md) 0;\n padding: var(--space-md);\n border-left: 4px solid var(--color-warning);\n background: var(--color-bg-secondary);\n }\n \n blockquote p:first-child { margin-top: 0; }\n blockquote p:last-child { margin-bottom: 0; }\n \n /* Lists */\n ul, ol {\n padding-left: var(--space-lg);\n }\n \n li { margin: var(--space-sm) 0; }\n \n /* Doc list (index page) */\n .doc-list {\n list-style: none;\n padding: 0;\n }\n \n .doc-list li {\n padding: var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--border-radius);\n margin-bottom: var(--space-md);\n }\n \n .doc-list a {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n }\n \n .doc-list .version {\n color: var(--color-text-muted);\n font-size: 0.875em;\n }\n \n .doc-list p {\n margin: var(--space-sm) 0 0;\n color: var(--color-text-muted);\n }\n \n /* Header */\n header {\n margin-bottom: var(--space-lg);\n }\n \n .breadcrumb {\n font-size: 0.875em;\n color: var(--color-text-muted);\n }\n \n .breadcrumb a {\n color: inherit;\n }\n \n /* Footer */\n footer {\n margin-top: var(--space-xl);\n padding-top: var(--space-lg);\n border-top: 1px solid var(--color-border);\n font-size: 0.875em;\n color: var(--color-text-muted);\n }\n \n .determinism code {\n font-size: 0.75em;\n }\n \n /* Theme toggle */\n .theme-toggle {\n position: fixed;\n top: var(--space-md);\n right: var(--space-md);\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--border-radius);\n background: var(--color-bg);\n cursor: pointer;\n font-size: 0.875em;\n }\n \n /* Responsive */\n @media (max-width: 600px) {\n .container { padding: var(--space-md); }\n h1 { font-size: 1.5rem; }\n h2 { font-size: 1.25rem; }\n table { font-size: 0.875em; }\n }\n `;\n}\n\nfunction getThemeScript(): string {\n return `\n // Theme toggle\n const toggle = document.createElement('button');\n toggle.className = 'theme-toggle';\n toggle.textContent = '🌙';\n toggle.onclick = () => {\n const html = document.documentElement;\n const isDark = html.dataset.theme === 'dark';\n html.dataset.theme = isDark ? 'light' : 'dark';\n toggle.textContent = isDark ? '🌙' : '☀️';\n localStorage.setItem('theme', html.dataset.theme);\n };\n document.body.appendChild(toggle);\n \n // Restore saved theme\n const saved = localStorage.getItem('theme');\n if (saved) {\n document.documentElement.dataset.theme = saved;\n toggle.textContent = saved === 'dark' ? '☀️' : '🌙';\n } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {\n document.documentElement.dataset.theme = 'dark';\n toggle.textContent = '☀️';\n }\n `;\n}\n","import { resolve } from 'node:path';\nimport { parseManifest } from '../../core/parser/manifestParser.js';\nimport { buildDocIR } from '../../core/ir/builder.js';\nimport { validateDocIR, formatValidationResult } from '../../core/ir/validator.js';\n\nexport interface ValidateOptions {\n strict?: boolean;\n}\n\nexport async function validate(repoPath: string, options: ValidateOptions = {}): Promise<boolean> {\n const absPath = resolve(repoPath);\n\n console.log(`Validating: ${absPath}`);\n console.log(`Mode: ${options.strict ? 'strict' : 'normal'}`);\n console.log('');\n\n try {\n // Parse manifest\n const manifestResult = await parseManifest(absPath);\n\n // Build Doc IR\n const ir = buildDocIR(manifestResult);\n\n // Validate\n const result = validateDocIR(ir, { strict: options.strict });\n\n // Format and print result\n console.log(formatValidationResult(result, absPath));\n\n return result.valid;\n } catch (error) {\n console.error('✗ Validation failed');\n console.error('');\n console.error(`Error: ${error instanceof Error ? error.message : error}`);\n return false;\n }\n}\n","/**\n * Known capabilities allowlist\n * Safety-affecting capabilities trigger stricter validation\n */\n\nexport const KNOWN_CAPABILITIES = [\n 'network',\n 'filesystem',\n 'secrets',\n 'exec',\n 'subprocess',\n 'database',\n 'queue',\n] as const;\n\nexport type KnownCapability = (typeof KNOWN_CAPABILITIES)[number];\n\n/**\n * Capabilities that imply safety-critical operations\n * Unknown capabilities matching these patterns fail in --strict mode\n */\nexport const SAFETY_AFFECTING_PATTERNS = ['network', 'exec', 'subprocess', 'write', 'delete'];\n\nexport function isKnownCapability(capability: string): capability is KnownCapability {\n return KNOWN_CAPABILITIES.includes(capability as KnownCapability);\n}\n\nexport function isSafetyAffecting(capability: string): boolean {\n return SAFETY_AFFECTING_PATTERNS.some((pattern) =>\n capability.toLowerCase().includes(pattern.toLowerCase())\n );\n}\n","import type { DocIR, ProvenanceSource } from '../ir/types.js';\nimport { isKnownCapability, isSafetyAffecting } from '../capabilities.js';\n\nexport type ValidationSeverity = 'error' | 'warning';\n\nexport interface ValidationIssue {\n severity: ValidationSeverity;\n code: string;\n message: string;\n path?: string;\n provenance?: ProvenanceSource;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n issues: ValidationIssue[];\n}\n\nexport interface ValidateOptions {\n strict?: boolean;\n}\n\n/**\n * Validate Doc IR for completeness and consistency\n */\nexport function validateDocIR(ir: DocIR, options: ValidateOptions = {}): ValidationResult {\n const issues: ValidationIssue[] = [];\n\n // Required field checks\n if (!ir.entity.id) {\n issues.push({\n severity: 'error',\n code: 'MISSING_TOOL_ID',\n message: 'Tool ID is required',\n path: 'entity.id',\n });\n }\n\n if (!ir.entity.version) {\n issues.push({\n severity: 'error',\n code: 'MISSING_VERSION',\n message: 'Version is required',\n path: 'entity.version',\n });\n }\n\n if (!ir.inputs?.schema && !ir.inputs?.parameters?.length) {\n issues.push({\n severity: 'error',\n code: 'MISSING_PARAMETERS_SCHEMA',\n message: 'Parameters schema is required',\n path: 'inputs',\n });\n }\n\n // Capability validation\n if (ir.constraints?.capabilities) {\n for (const cap of ir.constraints.capabilities) {\n if (!isKnownCapability(cap.type)) {\n const isSafety = isSafetyAffecting(cap.type);\n issues.push({\n severity: options.strict && isSafety ? 'error' : 'warning',\n code: 'UNKNOWN_CAPABILITY',\n message: `Unknown capability: ${cap.type}${isSafety ? ' (safety-affecting)' : ''}`,\n path: `constraints.capabilities.${cap.type}`,\n provenance: cap.provenance,\n });\n }\n }\n }\n\n // Structural contradiction checks\n issues.push(...checkStructuralContradictions(ir));\n\n const hasErrors = issues.some((i) => i.severity === 'error');\n\n return {\n valid: !hasErrors,\n issues,\n };\n}\n\n/**\n * Check for structural contradictions between sources\n */\nfunction checkStructuralContradictions(ir: DocIR): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n // Check if narrative mentions parameters not in schema\n if (ir.narrative?.notes && ir.inputs?.parameters) {\n const schemaParams = new Set(ir.inputs.parameters.map((p) => p.name.toLowerCase()));\n\n for (const note of ir.narrative.notes) {\n // Match patterns like \"parameter X\" or \"the X parameter\"\n const paramMentions = note.match(/(?:parameter|param)\\s+[`\"']?(\\w+)[`\"']?/gi) ?? [];\n const theParamMentions = note.match(/the\\s+[`\"']?(\\w+)[`\"']?\\s+parameter/gi) ?? [];\n\n for (const match of [...paramMentions, ...theParamMentions]) {\n const paramName = match.replace(/.*?[`\"']?(\\w+)[`\"']?.*/i, '$1').toLowerCase();\n if (paramName && !schemaParams.has(paramName) && paramName !== 'parameter') {\n issues.push({\n severity: 'error',\n code: 'NARRATIVE_REFERENCES_UNDEFINED_PARAM',\n message: `Narrative references parameter \"${paramName}\" not in schema`,\n path: 'narrative.notes',\n provenance: 'narrative',\n });\n }\n }\n }\n }\n\n // Check if examples use parameters not in schema\n if (ir.narrative?.examples && ir.inputs?.parameters) {\n const schemaParams = new Set(ir.inputs.parameters.map((p) => p.name));\n\n for (const example of ir.narrative.examples) {\n if (example.input && typeof example.input === 'object') {\n for (const key of Object.keys(example.input as Record<string, unknown>)) {\n if (!schemaParams.has(key)) {\n issues.push({\n severity: 'warning',\n code: 'EXAMPLE_USES_UNDEFINED_PARAM',\n message: `Example uses parameter \"${key}\" not in schema`,\n path: `narrative.examples.${example.title ?? 'unnamed'}`,\n provenance: 'narrative',\n });\n }\n }\n }\n }\n }\n\n // Check for side effect / capability contradictions\n if (ir.overview?.sideEffects && ir.constraints?.capabilities) {\n const capTypes = new Set(ir.constraints.capabilities.map((c) => c.type));\n\n for (const effect of ir.overview.sideEffects) {\n // Map side effect types to capability types\n const expectedCap = mapSideEffectToCapability(effect.type);\n if (expectedCap && !capTypes.has(expectedCap)) {\n issues.push({\n severity: 'error',\n code: 'SIDE_EFFECT_CAPABILITY_MISMATCH',\n message: `Side effect \"${effect.type}\" requires capability \"${expectedCap}\" which is not declared`,\n path: `overview.sideEffects.${effect.type}`,\n provenance: effect.provenance,\n });\n }\n }\n }\n\n return issues;\n}\n\nfunction mapSideEffectToCapability(effectType: string): string | null {\n const mapping: Record<string, string> = {\n filesystem: 'filesystem',\n network: 'network',\n secrets: 'secrets',\n exec: 'exec',\n subprocess: 'subprocess',\n database: 'database',\n queue: 'queue',\n };\n return mapping[effectType] ?? null;\n}\n\n/**\n * Format validation result for CLI output\n */\nexport function formatValidationResult(result: ValidationResult, repoPath: string): string {\n const lines: string[] = [];\n\n lines.push(`Validating: ${repoPath}`);\n lines.push('');\n\n if (result.valid) {\n lines.push('✓ Validation passed');\n } else {\n lines.push('✗ Validation failed');\n }\n lines.push('');\n\n const errors = result.issues.filter((i) => i.severity === 'error');\n const warnings = result.issues.filter((i) => i.severity === 'warning');\n\n if (errors.length > 0) {\n lines.push(`Errors (${errors.length}):`);\n for (const issue of errors) {\n lines.push(` ✗ [${issue.code}] ${issue.message}`);\n if (issue.path) {\n lines.push(` at ${issue.path}`);\n }\n }\n lines.push('');\n }\n\n if (warnings.length > 0) {\n lines.push(`Warnings (${warnings.length}):`);\n for (const issue of warnings) {\n lines.push(` ⚠ [${issue.code}] ${issue.message}`);\n if (issue.path) {\n lines.push(` at ${issue.path}`);\n }\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Serve Command\n *\n * Start a local development server for generated documentation.\n * Enforces safe defaults per deployment stance:\n * - localhost binding\n * - mutations disabled\n * - SSE auto-switch for non-localhost\n */\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { OddDocsServer, type ServeOptions } from '../../server/index.js';\nimport { generate } from './generate.js';\n\nexport interface ServeCommandOptions {\n port?: number;\n host?: string;\n output?: string;\n watch?: boolean;\n watchMode?: 'auto' | 'poll';\n reload?: 'ws' | 'sse' | 'poll' | 'none';\n open?: boolean;\n introspect?: string;\n enableMutations?: boolean;\n mutationToken?: string;\n}\n\n/**\n * Serve documentation with live reload\n */\nexport async function serve(repoPath: string, options: ServeCommandOptions = {}): Promise<void> {\n const resolvedPath = resolve(repoPath);\n\n // Determine output directory\n const outputDir = options.output\n ? resolve(options.output)\n : join(resolvedPath, 'docs', 'generated');\n\n // Check if docs exist, generate if not\n if (!existsSync(outputDir)) {\n console.log('[odd-docs] Documentation not found, generating...');\n await generate(repoPath, { output: outputDir, format: 'html' });\n }\n\n // Determine reload mode\n let reloadMode: 'ws' | 'sse' | 'poll' | 'none' = options.reload ?? 'ws';\n\n // Use poll mode if explicitly requested via env or option\n if (options.watchMode === 'poll' || process.env.CHOKIDAR_USEPOLLING === '1') {\n reloadMode = 'poll';\n console.log('[odd-docs] Using poll-based watching (CPU intensive)');\n }\n\n const host = options.host ?? 'localhost';\n const port = options.port ?? 3000;\n\n // Auto-switch to SSE for non-localhost (safer for K8s)\n if (host !== 'localhost' && options.reload === undefined) {\n reloadMode = 'sse';\n console.log('[odd-docs] Using SSE for non-localhost binding');\n }\n\n // Create and start server\n const serverOptions: Partial<ServeOptions> & { outputDir: string } = {\n outputDir,\n host,\n port,\n watch: options.watch !== false,\n reloadMode,\n enableMutations: options.enableMutations ?? false,\n mutationToken: options.mutationToken,\n };\n\n const server = new OddDocsServer(serverOptions);\n\n // Handle shutdown\n const shutdown = async () => {\n console.log('\\n[odd-docs] Shutting down...');\n await server.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n try {\n await server.start();\n\n // Open browser if requested\n if (options.open !== false && host === 'localhost') {\n const url = `http://${host}:${port}`;\n try {\n const { default: open } = await import('open');\n await open(url);\n } catch {\n console.log(`[odd-docs] Open browser manually: ${url}`);\n }\n }\n } catch (error) {\n console.error('[odd-docs] Failed to start server:', error);\n process.exit(1);\n }\n}\n","/**\n * OddDocs Server\n *\n * HTTP server wrapper for serving generated documentation.\n * Enforces safe defaults: localhost binding, no mutations without explicit opt-in.\n */\n\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { FileServer } from './fileServer.js';\nimport { LiveReload } from './livereload.js';\nimport { ApiHandler, type ServerState } from './api.js';\n\nexport interface ServeOptions {\n /** Port to listen on. Default: 3000 */\n port: number;\n /** Host to bind. Default: 'localhost' (safe) */\n host: string;\n /** Documentation output directory */\n outputDir: string;\n /** Enable file watching for live reload. Default: true */\n watch: boolean;\n /** Reload mechanism. Default: 'ws' for localhost, 'sse' for 0.0.0.0 */\n reloadMode: 'ws' | 'sse' | 'poll' | 'none';\n /** Enable mutation API endpoints. Default: false */\n enableMutations: boolean;\n /** Token for mutation endpoints. Required if enableMutations=true */\n mutationToken?: string;\n /** Request timeout in ms. Default: 30000 */\n requestTimeout: number;\n}\n\nexport const DEFAULT_OPTIONS: Omit<ServeOptions, 'outputDir'> = {\n port: 3000,\n host: 'localhost',\n watch: true,\n reloadMode: 'ws',\n enableMutations: false,\n requestTimeout: 30000,\n};\n\nexport class OddDocsServer {\n private server: Server | null = null;\n private fileServer: FileServer;\n private liveReload: LiveReload | null = null;\n private apiHandler: ApiHandler;\n private options: ServeOptions;\n private state: ServerState;\n\n constructor(options: Partial<ServeOptions> & { outputDir: string }) {\n // Apply defaults\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n // Auto-switch to SSE for non-localhost binding (safer for K8s)\n reloadMode:\n options.reloadMode ??\n (options.host && options.host !== 'localhost' ? 'sse' : DEFAULT_OPTIONS.reloadMode),\n };\n\n // Environment overrides\n this.options.host = process.env.ODD_DOCS_HOST ?? this.options.host;\n this.options.port = parseInt(process.env.ODD_DOCS_PORT ?? String(this.options.port), 10);\n this.options.mutationToken = process.env.ODD_DOCS_MUTATION_TOKEN ?? this.options.mutationToken;\n\n this.state = {\n lastGenerateSuccess: true,\n lastGenerateTime: new Date().toISOString(),\n outputDirAccessible: true,\n introspectionConnected: false,\n };\n\n this.fileServer = new FileServer(this.options.outputDir);\n this.apiHandler = new ApiHandler(this.state, this.options);\n }\n\n async start(): Promise<void> {\n // Validate mutation token if mutations enabled\n if (this.options.enableMutations && !this.options.mutationToken) {\n throw new Error(\n 'Mutation token required when --enable-mutations is set. ' +\n 'Set ODD_DOCS_MUTATION_TOKEN or --mutation-token'\n );\n }\n\n this.server = createServer((req, res) => this.handleRequest(req, res));\n\n // Set timeout\n this.server.timeout = this.options.requestTimeout;\n\n // Start live reload if enabled\n if (this.options.watch && this.options.reloadMode !== 'none') {\n this.liveReload = new LiveReload({\n outputDir: this.options.outputDir,\n mode: this.options.reloadMode,\n server: this.server,\n });\n await this.liveReload.start();\n }\n\n return new Promise((resolve, reject) => {\n this.server!.listen(this.options.port, this.options.host, () => {\n console.log(\n `[odd-docs] Server started at http://${this.options.host}:${this.options.port}`\n );\n console.log(`[odd-docs] Serving: ${this.options.outputDir}`);\n if (this.liveReload) {\n console.log(`[odd-docs] Live reload: ${this.options.reloadMode}`);\n }\n resolve();\n });\n\n this.server!.on('error', reject);\n });\n }\n\n async stop(): Promise<void> {\n if (this.liveReload) {\n await this.liveReload.stop();\n }\n if (this.server) {\n return new Promise((resolve) => {\n this.server!.close(() => resolve());\n });\n }\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url ?? '/';\n\n try {\n // API routes\n if (url.startsWith('/api/')) {\n await this.apiHandler.handle(req, res);\n return;\n }\n\n // Live reload endpoints\n if (this.liveReload && url === '/__livereload') {\n await this.liveReload.handleRequest(req, res);\n return;\n }\n\n // Static file serving\n await this.fileServer.serve(req, res);\n } catch (error) {\n console.error('[odd-docs] Request error:', error);\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n }\n\n updateState(updates: Partial<ServerState>): void {\n Object.assign(this.state, updates);\n }\n}\n","/**\n * File Server\n *\n * Static file serving with security protections.\n * - Path traversal protection via realpath + relative check\n * - MIME type detection\n * - ETag/304 support\n * - Max response size cap\n */\n\nimport { createReadStream, statSync } from 'node:fs';\nimport { realpath } from 'node:fs/promises';\nimport { join, extname, relative, isAbsolute } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst MAX_RESPONSE_SIZE = 50 * 1024 * 1024; // 50MB\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.md': 'text/markdown; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n};\n\nexport class FileServer {\n private rootDir: string;\n private resolvedRoot: string | null = null;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n async serve(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n let pathname = decodeURIComponent(url.pathname);\n\n // Default to index.html\n if (pathname === '/' || pathname.endsWith('/')) {\n pathname = join(pathname, 'index.html');\n }\n\n // Resolve and validate path\n const filePath = await this.resolvePath(pathname);\n if (!filePath) {\n res.statusCode = 403;\n res.end('Forbidden: Path traversal blocked');\n return;\n }\n\n // Check file exists and get stats\n let stats;\n try {\n stats = statSync(filePath);\n } catch {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n\n if (!stats.isFile()) {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n\n // Check size limit\n if (stats.size > MAX_RESPONSE_SIZE) {\n res.statusCode = 413;\n res.end('File too large');\n return;\n }\n\n // ETag handling\n const etag = this.computeETag(filePath, stats.mtime, stats.size);\n const ifNoneMatch = req.headers['if-none-match'];\n if (ifNoneMatch === etag) {\n res.statusCode = 304;\n res.end();\n return;\n }\n\n // Set headers\n const ext = extname(filePath).toLowerCase();\n const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';\n\n res.setHeader('Content-Type', contentType);\n res.setHeader('Content-Length', stats.size);\n res.setHeader('ETag', etag);\n res.setHeader('Cache-Control', 'no-cache');\n\n // Stream file\n const stream = createReadStream(filePath);\n stream.pipe(res);\n stream.on('error', () => {\n res.statusCode = 500;\n res.end('Error reading file');\n });\n }\n\n /**\n * Resolve path with traversal protection\n */\n private async resolvePath(pathname: string): Promise<string | null> {\n // Ensure we have the real root path\n if (!this.resolvedRoot) {\n try {\n this.resolvedRoot = await realpath(this.rootDir);\n } catch {\n return null;\n }\n }\n\n // Construct target path\n const targetPath = join(this.rootDir, pathname);\n\n // Resolve to real path (follows symlinks, canonicalizes)\n let resolvedTarget: string;\n try {\n resolvedTarget = await realpath(targetPath);\n } catch {\n return null;\n }\n\n // Check containment: resolved path must be within root\n const rel = relative(this.resolvedRoot, resolvedTarget);\n if (rel.startsWith('..') || isAbsolute(rel)) {\n // Path escapes root directory\n console.warn(`[odd-docs] Path traversal blocked: ${pathname}`);\n return null;\n }\n\n return resolvedTarget;\n }\n\n private computeETag(path: string, mtime: Date, size: number): string {\n const hash = createHash('md5')\n .update(`${path}:${mtime.getTime()}:${size}`)\n .digest('hex')\n .slice(0, 16);\n return `\"${hash}\"`;\n }\n}\n","/**\n * Live Reload\n *\n * File watching and live reload for development.\n * Supports multiple mechanisms: WebSocket, SSE, Polling.\n * WS is dev-only default; SSE is K8s-safe.\n */\n\nimport { watch, type FSWatcher } from 'node:fs';\nimport type { Server, IncomingMessage, ServerResponse } from 'node:http';\n\nexport interface LiveReloadOptions {\n outputDir: string;\n mode: 'ws' | 'sse' | 'poll' | 'none';\n server: Server;\n pollInterval?: number; // for poll mode, ms\n}\n\ntype ReloadMode = 'ws' | 'sse' | 'poll' | 'none';\n\nexport class LiveReload {\n private options: LiveReloadOptions;\n private watcher: FSWatcher | null = null;\n private sseClients: Set<ServerResponse> = new Set();\n private lastChangeTime: number = Date.now();\n private debounceTimer: NodeJS.Timeout | null = null;\n\n constructor(options: LiveReloadOptions) {\n this.options = {\n pollInterval: 5000,\n ...options,\n };\n }\n\n async start(): Promise<void> {\n // Start file watcher with debounce\n const usePolling = process.env.CHOKIDAR_USEPOLLING === '1' || this.options.mode === 'poll';\n\n this.watcher = watch(\n this.options.outputDir,\n { recursive: true, persistent: true },\n (_eventType, filename) => {\n if (filename) {\n this.onFileChange(filename);\n }\n }\n );\n\n if (usePolling) {\n console.log('[odd-docs] Using poll-based file watching');\n }\n\n console.log(`[odd-docs] Live reload started (mode: ${this.options.mode})`);\n }\n\n async stop(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n if (this.watcher) {\n this.watcher.close();\n }\n // Close SSE connections\n for (const client of this.sseClients) {\n client.end();\n }\n this.sseClients.clear();\n }\n\n private onFileChange(filename: string): void {\n // Debounce rapid changes\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.lastChangeTime = Date.now();\n console.log(`[odd-docs] Change detected: ${filename}`);\n this.notifyClients();\n }, 100);\n }\n\n private notifyClients(): void {\n const message = JSON.stringify({ type: 'reload', time: this.lastChangeTime });\n\n // Notify SSE clients\n for (const client of this.sseClients) {\n client.write(`data: ${message}\\n\\n`);\n }\n }\n\n async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const mode = this.options.mode;\n\n if (mode === 'sse') {\n // SSE endpoint\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no'); // For nginx\n\n res.write(': ping\\n\\n');\n this.sseClients.add(res);\n\n req.on('close', () => {\n this.sseClients.delete(res);\n });\n } else if (mode === 'poll') {\n // Poll endpoint - return last change time\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ lastChange: this.lastChangeTime }));\n } else {\n // Not supported in this mode\n res.statusCode = 404;\n res.end('Live reload not available in this mode');\n }\n }\n\n /**\n * Get client-side script for live reload\n */\n static getClientScript(mode: ReloadMode, pollInterval: number = 5000): string {\n if (mode === 'none') return '';\n\n if (mode === 'sse') {\n return `\n<script>\n(function() {\n const es = new EventSource('/__livereload');\n es.onmessage = function(e) {\n const data = JSON.parse(e.data);\n if (data.type === 'reload') {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n };\n es.onerror = function() {\n console.log('[odd-docs] SSE connection lost, will retry...');\n };\n})();\n</script>`;\n }\n\n if (mode === 'poll') {\n return `\n<script>\n(function() {\n let lastChange = 0;\n setInterval(async () => {\n try {\n const res = await fetch('/__livereload');\n const data = await res.json();\n if (lastChange && data.lastChange > lastChange) {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n lastChange = data.lastChange;\n } catch (e) {}\n }, ${pollInterval});\n})();\n</script>`;\n }\n\n // WebSocket (ws mode) - requires separate ws server\n return `\n<script>\n(function() {\n const ws = new WebSocket('ws://' + location.host + '/__ws');\n ws.onmessage = function(e) {\n const data = JSON.parse(e.data);\n if (data.type === 'reload') {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n };\n ws.onclose = function() {\n console.log('[odd-docs] WebSocket closed, will retry in 3s...');\n setTimeout(() => location.reload(), 3000);\n };\n})();\n</script>`;\n }\n}\n","/**\n * API Handler\n *\n * REST API endpoints for programmatic access.\n * Implements K8s-compatible health semantics.\n * Mutation endpoints require explicit opt-in + token.\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { ServeOptions } from './index.js';\n\nconst MAX_IR_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport interface ServerState {\n lastGenerateSuccess: boolean;\n lastGenerateTime: string;\n outputDirAccessible: boolean;\n introspectionConnected: boolean;\n lastIntrospectionTime?: string;\n}\n\nexport class ApiHandler {\n private state: ServerState;\n private options: ServeOptions;\n\n constructor(state: ServerState, options: ServeOptions) {\n this.state = state;\n this.options = options;\n }\n\n async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n // Route to handlers\n switch (path) {\n case '/api/health':\n return this.handleHealth(res);\n case '/api/ready':\n return this.handleReady(res);\n case '/api/introspection':\n return this.handleIntrospection(res);\n case '/api/docs':\n return this.handleDocs(res);\n case '/api/ir':\n return this.handleIR(res);\n case '/api/capabilities':\n return this.handleCapabilities(res);\n case '/api/regenerate':\n if (method === 'POST') {\n return this.handleRegenerate(req, res);\n }\n return this.methodNotAllowed(res);\n default:\n return this.notFound(res);\n }\n }\n\n /**\n * GET /api/health - Liveness probe\n * Returns 200 if process is running\n */\n private handleHealth(res: ServerResponse): void {\n this.json(res, {\n status: 'ok',\n timestamp: new Date().toISOString(),\n });\n }\n\n /**\n * GET /api/ready - Readiness probe\n * Returns 200 if last generate succeeded and output is accessible\n */\n private handleReady(res: ServerResponse): void {\n const ready = this.state.lastGenerateSuccess && this.state.outputDirAccessible;\n\n if (!ready) {\n res.statusCode = 503;\n }\n\n this.json(res, {\n ready,\n lastGenerateSuccess: this.state.lastGenerateSuccess,\n lastGenerateTime: this.state.lastGenerateTime,\n outputDirAccessible: this.state.outputDirAccessible,\n });\n }\n\n /**\n * GET /api/introspection - Introspection status\n */\n private handleIntrospection(res: ServerResponse): void {\n this.json(res, {\n connected: this.state.introspectionConnected,\n lastPollTime: this.state.lastIntrospectionTime ?? null,\n });\n }\n\n /**\n * GET /api/docs - List documentation sections\n */\n private handleDocs(res: ServerResponse): void {\n // TODO: Implement actual doc listing\n this.json(res, {\n sections: [],\n message: 'Not implemented yet',\n });\n }\n\n /**\n * GET /api/ir - Full IR dump (capped at 10MB)\n */\n private handleIR(res: ServerResponse): void {\n // TODO: Implement actual IR retrieval\n const ir = { tools: [], prompts: [], resources: [] };\n const irJson = JSON.stringify(ir);\n\n if (irJson.length > MAX_IR_SIZE) {\n this.json(res, {\n truncated: true,\n message: `IR exceeds ${MAX_IR_SIZE / 1024 / 1024}MB limit`,\n partial: null,\n });\n return;\n }\n\n res.setHeader('Content-Type', 'application/json');\n res.end(irJson);\n }\n\n /**\n * GET /api/capabilities - Tool capabilities summary\n */\n private handleCapabilities(res: ServerResponse): void {\n this.json(res, {\n serve: {\n host: this.options.host,\n port: this.options.port,\n reloadMode: this.options.reloadMode,\n mutationsEnabled: this.options.enableMutations,\n },\n });\n }\n\n /**\n * POST /api/regenerate - Trigger manual regeneration\n * Requires --enable-mutations and valid token\n */\n private handleRegenerate(req: IncomingMessage, res: ServerResponse): void {\n // Check if mutations are enabled\n if (!this.options.enableMutations) {\n res.statusCode = 403;\n this.json(res, {\n error: 'Mutations disabled',\n message: 'Start server with --enable-mutations to use this endpoint',\n });\n return;\n }\n\n // Validate token\n const token = req.headers['x-mutation-token'];\n if (token !== this.options.mutationToken) {\n res.statusCode = 401;\n this.json(res, {\n error: 'Unauthorized',\n message: 'Invalid or missing X-Mutation-Token header',\n });\n return;\n }\n\n // TODO: Trigger actual regeneration\n this.json(res, {\n status: 'queued',\n message: 'Regeneration triggered',\n timestamp: new Date().toISOString(),\n });\n }\n\n private json(res: ServerResponse, data: unknown): void {\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data, null, 2));\n }\n\n private notFound(res: ServerResponse): void {\n res.statusCode = 404;\n this.json(res, { error: 'Not Found' });\n }\n\n private methodNotAllowed(res: ServerResponse): void {\n res.statusCode = 405;\n this.json(res, { error: 'Method Not Allowed' });\n }\n}\n"],"mappings":"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","names":["join","join","join","resolve","resolve","join","resolve","join","createHash","resolve","resolve","join","join"]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/commands/generate.ts","../../src/core/parser/manifestParser.ts","../../src/core/ir/builder.ts","../../src/core/parser/schemaParser.ts","../../src/core/renderer/markdownRenderer.ts","../../src/core/renderer/htmlRenderer.ts","../../src/cli/commands/validate.ts","../../src/core/capabilities.ts","../../src/core/ir/validator.ts","../../src/cli/commands/serve.ts","../../src/server/index.ts","../../src/server/fileServer.ts","../../src/server/livereload.ts","../../src/server/api.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { generate } from './commands/generate.js';\nimport { validate } from './commands/validate.js';\nimport { serve } from './commands/serve.js';\n\n// Use createRequire for cross-platform compatibility with npx\n// This approach works reliably when the package is installed via npm/npx\nconst require = createRequire(import.meta.url);\nconst packageJson = require('../../package.json') as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('odd-docs')\n .description('MCP-native documentation generator')\n .version(packageJson.version);\n\nprogram\n .command('generate')\n .description('Generate documentation for an MCP repo')\n .argument('<repo-path>', 'Path to the repository')\n .option('-f, --format <format>', 'Output format: md, html, or both', 'md')\n .option('-o, --output <dir>', 'Output directory')\n .option('--introspect <url>', 'MCP server URL for live introspection')\n .action(async (repoPath: string, options) => {\n try {\n await generate(repoPath, {\n format: options.format,\n output: options.output,\n introspect: options.introspect,\n });\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('validate')\n .description('Validate documentation inputs for an MCP repo')\n .argument('<repo-path>', 'Path to the repository')\n .option('-s, --strict', 'Fail on unknown safety-affecting capabilities')\n .action(async (repoPath: string, options) => {\n try {\n const valid = await validate(repoPath, { strict: options.strict });\n process.exit(valid ? 0 : 1);\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram\n .command('serve')\n .description('Start a local dev server for generated documentation')\n .argument('<repo-path>', 'Path to the repository')\n .option('-p, --port <port>', 'Port to listen on', '3000')\n .option('-H, --host <host>', 'Host to bind (default: localhost for safety)', 'localhost')\n .option('-o, --output <dir>', 'Documentation output directory')\n .option('--no-watch', 'Disable file watching')\n .option('--watch-mode <mode>', 'Watch mode: auto or poll (use poll for Docker/NFS)', 'auto')\n .option('--reload <mode>', 'Reload mechanism: ws, sse, poll, none', 'ws')\n .option('--no-open', 'Do not open browser on start')\n .option('--introspect <target>', 'MCP target: http://host:port or stdio:<cmd>')\n .option('--enable-mutations', 'Enable mutation API endpoints (requires token)')\n .option('--mutation-token <token>', 'Token for mutation endpoints (or ODD_DOCS_MUTATION_TOKEN)')\n .action(async (repoPath: string, options) => {\n try {\n await serve(repoPath, {\n port: parseInt(options.port, 10),\n host: options.host,\n output: options.output,\n watch: options.watch,\n watchMode: options.watchMode,\n reload: options.reload,\n open: options.open,\n introspect: options.introspect,\n enableMutations: options.enableMutations,\n mutationToken: options.mutationToken,\n });\n } catch (error) {\n console.error('Error:', error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nprogram.parse();\n","import { writeFile, mkdir } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { parseManifest } from '../../core/parser/manifestParser.js';\nimport { buildDocIR } from '../../core/ir/builder.js';\nimport { renderMarkdown } from '../../core/renderer/markdownRenderer.js';\nimport { renderHTML } from '../../core/renderer/htmlRenderer.js';\n\nexport interface GenerateOptions {\n format?: 'md' | 'html' | 'both';\n output?: string;\n introspect?: string;\n}\n\nexport async function generate(repoPath: string, options: GenerateOptions = {}): Promise<void> {\n const absPath = resolve(repoPath);\n const format = options.format ?? 'md';\n const outputDir = options.output ? resolve(options.output) : join(absPath, 'docs', 'generated');\n\n console.log(`Generating documentation for: ${absPath}`);\n\n // Parse manifest\n const manifestResult = await parseManifest(absPath);\n console.log(` Entity: ${manifestResult.entity.id}@${manifestResult.entity.version}`);\n\n // Build Doc IR\n const ir = buildDocIR(manifestResult);\n console.log(` Determinism key: ${ir.determinismKey}`);\n\n // Ensure output directory exists\n await mkdir(outputDir, { recursive: true });\n\n // Render formats\n if (format === 'md' || format === 'both') {\n const markdown = renderMarkdown(ir);\n const mdPath = join(outputDir, `${ir.entity.id}.md`);\n await writeFile(mdPath, markdown, 'utf-8');\n console.log(` ✓ Markdown: ${mdPath}`);\n }\n\n if (format === 'html' || format === 'both') {\n const html = renderHTML(ir);\n const htmlPath = join(outputDir, `${ir.entity.id}.html`);\n await writeFile(htmlPath, html, 'utf-8');\n console.log(` ✓ HTML: ${htmlPath}`);\n }\n\n // Write IR for debugging/caching\n const irPath = join(outputDir, `${ir.entity.id}.ir.json`);\n await writeFile(irPath, JSON.stringify(ir, null, 2), 'utf-8');\n console.log(` ✓ Doc IR: ${irPath}`);\n\n console.log('Done!');\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type { DocIR, Capability, SchemaSection } from '../ir/types.js';\n\ninterface ToolManifest {\n tool_id: string;\n version: string;\n description?: string;\n execution_mode?: 'IN_PROCESS' | 'RUNNER';\n parameters?: Record<string, unknown>;\n capabilities?: {\n network?: string[];\n filesystem?: string[];\n secrets?: string[];\n };\n timeout_ms?: number;\n resource_limits?: {\n memory_mb?: number;\n cpu_cores?: number;\n };\n deprecation?: {\n deprecated_at: string;\n sunset_date: string;\n migration_url?: string;\n };\n}\n\nexport interface ManifestParseResult {\n entity: DocIR['entity'];\n inputs: SchemaSection;\n constraints?: DocIR['constraints'];\n lifecycle?: DocIR['lifecycle'];\n}\n\n/**\n * Parse an MCP tool manifest file into partial Doc IR\n */\nexport async function parseManifest(repoPath: string): Promise<ManifestParseResult> {\n const manifestPath = join(repoPath, 'manifest.json');\n\n let content: string;\n try {\n content = await readFile(manifestPath, 'utf-8');\n } catch {\n throw new Error(`Manifest not found: ${manifestPath}`);\n }\n\n let manifest: ToolManifest;\n try {\n manifest = JSON.parse(content) as ToolManifest;\n } catch {\n throw new Error(`Invalid JSON in manifest: ${manifestPath}`);\n }\n\n // Validate required fields\n if (!manifest.tool_id) {\n throw new Error('Manifest missing required field: tool_id');\n }\n if (!manifest.version) {\n throw new Error('Manifest missing required field: version');\n }\n\n // Build capabilities array\n const capabilities: Capability[] = [];\n if (manifest.capabilities) {\n for (const [type, values] of Object.entries(manifest.capabilities)) {\n if (Array.isArray(values) && values.length > 0) {\n capabilities.push({ type, values, provenance: 'manifest' });\n }\n }\n }\n\n const result: ManifestParseResult = {\n entity: {\n type: 'tool',\n id: manifest.tool_id,\n version: manifest.version,\n description: manifest.description,\n },\n inputs: {\n schema: manifest.parameters,\n provenance: 'manifest',\n },\n };\n\n // Add constraints if present\n if (capabilities.length > 0 || manifest.timeout_ms || manifest.resource_limits) {\n result.constraints = {\n capabilities: capabilities.length > 0 ? capabilities : undefined,\n timeoutMs: manifest.timeout_ms,\n resourceLimits: manifest.resource_limits\n ? {\n memoryMb: manifest.resource_limits.memory_mb,\n cpuCores: manifest.resource_limits.cpu_cores,\n }\n : undefined,\n };\n }\n\n // Add lifecycle if deprecation present\n if (manifest.deprecation) {\n result.lifecycle = {\n version: manifest.version,\n deprecation: {\n deprecatedAt: manifest.deprecation.deprecated_at,\n sunsetDate: manifest.deprecation.sunset_date,\n migrationUrl: manifest.deprecation.migration_url,\n },\n };\n }\n\n return result;\n}\n","import { createHash } from 'node:crypto';\nimport type { DocIR } from './types.js';\nimport { enrichSchemaSection } from '../parser/schemaParser.js';\nimport type { ManifestParseResult } from '../parser/manifestParser.js';\n\n/**\n * Build a complete Doc IR from parsed sources\n */\nexport function buildDocIR(manifest: ManifestParseResult): DocIR {\n const enrichedInputs = enrichSchemaSection(manifest.inputs);\n\n const ir: DocIR = {\n version: '1.0.0',\n generatedAt: new Date().toISOString(),\n determinismKey: '', // Computed below\n entity: manifest.entity,\n inputs: enrichedInputs,\n constraints: manifest.constraints,\n lifecycle: manifest.lifecycle,\n provenance: {\n entity: 'manifest',\n inputs: 'manifest',\n },\n };\n\n // Compute determinism key\n ir.determinismKey = computeDeterminismKey(ir);\n\n return ir;\n}\n\n/**\n * Compute SHA-256 determinism key for caching and diffing\n */\nexport function computeDeterminismKey(ir: Omit<DocIR, 'determinismKey' | 'generatedAt'>): string {\n const canonical = JSON.stringify({\n entity: ir.entity,\n inputs: ir.inputs,\n constraints: ir.constraints,\n lifecycle: ir.lifecycle,\n });\n\n const hash = createHash('sha256').update(canonical).digest('hex');\n return `sha256:${hash}`;\n}\n","import type { Parameter, SchemaSection } from '../ir/types.js';\n\ninterface JSONSchema {\n type?: string;\n properties?: Record<string, JSONSchema>;\n required?: string[];\n description?: string;\n default?: unknown;\n enum?: unknown[];\n minimum?: number;\n maximum?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n items?: JSONSchema;\n $ref?: string;\n}\n\n/**\n * Parse JSON Schema into a list of parameters for documentation\n */\nexport function parseSchema(schema: Record<string, unknown> | undefined): Parameter[] {\n if (!schema) return [];\n\n const jsonSchema = schema as JSONSchema;\n const parameters: Parameter[] = [];\n const required = new Set(jsonSchema.required ?? []);\n\n if (jsonSchema.properties) {\n for (const [name, propSchema] of Object.entries(jsonSchema.properties)) {\n parameters.push(parseProperty(name, propSchema, required.has(name)));\n }\n }\n\n return parameters;\n}\n\nfunction parseProperty(name: string, schema: JSONSchema, isRequired: boolean): Parameter {\n const param: Parameter = {\n name,\n type: resolveType(schema),\n required: isRequired,\n };\n\n if (schema.description) {\n param.description = schema.description;\n }\n\n if (schema.default !== undefined) {\n param.default = schema.default;\n }\n\n if (schema.enum) {\n param.enum = schema.enum;\n }\n\n // Build constraints string\n const constraints = buildConstraints(schema);\n if (constraints) {\n param.constraints = constraints;\n }\n\n return param;\n}\n\nfunction resolveType(schema: JSONSchema): string {\n if (schema.$ref) {\n // Extract type name from $ref\n const refParts = schema.$ref.split('/');\n return refParts[refParts.length - 1];\n }\n\n if (schema.enum) {\n return 'enum';\n }\n\n if (schema.type === 'array' && schema.items) {\n return `${resolveType(schema.items)}[]`;\n }\n\n return schema.type ?? 'unknown';\n}\n\nfunction buildConstraints(schema: JSONSchema): string | undefined {\n const parts: string[] = [];\n\n if (schema.minimum !== undefined) {\n parts.push(`min: ${schema.minimum}`);\n }\n if (schema.maximum !== undefined) {\n parts.push(`max: ${schema.maximum}`);\n }\n if (schema.minLength !== undefined) {\n parts.push(`minLength: ${schema.minLength}`);\n }\n if (schema.maxLength !== undefined) {\n parts.push(`maxLength: ${schema.maxLength}`);\n }\n if (schema.pattern) {\n parts.push(`pattern: ${schema.pattern}`);\n }\n\n return parts.length > 0 ? parts.join(', ') : undefined;\n}\n\n/**\n * Enrich a SchemaSection with parsed parameters\n */\nexport function enrichSchemaSection(section: SchemaSection): SchemaSection {\n return {\n ...section,\n parameters: parseSchema(section.schema),\n };\n}\n","import type { DocIR, Parameter, ProvenanceSource } from '../ir/types.js';\n\n/**\n * Render Doc IR to Markdown\n */\nexport function renderMarkdown(ir: DocIR): string {\n const lines: string[] = [];\n\n // Header\n lines.push(`# ${ir.entity.id}`);\n lines.push('');\n lines.push(`**Version:** ${ir.entity.version} `);\n lines.push(`**Type:** ${ir.entity.type} `);\n if (ir.entity.description) {\n lines.push('');\n lines.push(ir.entity.description);\n }\n lines.push('');\n\n // Overview\n if (ir.overview) {\n lines.push('## Overview');\n lines.push('');\n if (ir.overview.intent) {\n lines.push(`**Intent:** ${ir.overview.intent}`);\n lines.push('');\n }\n if (ir.overview.useCases?.length) {\n lines.push('### Use Cases');\n lines.push('');\n for (const useCase of ir.overview.useCases) {\n lines.push(`- ${useCase}`);\n }\n lines.push('');\n }\n if (ir.overview.sideEffects?.length) {\n lines.push('### Side Effects');\n lines.push('');\n for (const effect of ir.overview.sideEffects) {\n lines.push(\n `- **${effect.type}**: ${effect.description} ${provenanceBadge(effect.provenance)}`\n );\n }\n lines.push('');\n }\n }\n\n // Inputs\n if (ir.inputs?.parameters?.length) {\n lines.push('## Inputs');\n lines.push('');\n lines.push(provenanceBadge(ir.inputs.provenance));\n lines.push('');\n lines.push(renderParameterTable(ir.inputs.parameters));\n lines.push('');\n }\n\n // Outputs\n if (ir.outputs?.parameters?.length) {\n lines.push('## Outputs');\n lines.push('');\n lines.push(provenanceBadge(ir.outputs.provenance));\n lines.push('');\n lines.push(renderParameterTable(ir.outputs.parameters));\n lines.push('');\n }\n\n // Constraints\n if (ir.constraints) {\n lines.push('## Constraints');\n lines.push('');\n if (ir.constraints.capabilities?.length) {\n lines.push('### Capabilities');\n lines.push('');\n for (const cap of ir.constraints.capabilities) {\n const values = cap.values?.join(', ') ?? 'enabled';\n lines.push(`- **${cap.type}**: ${values} ${provenanceBadge(cap.provenance)}`);\n }\n lines.push('');\n }\n if (ir.constraints.timeoutMs) {\n lines.push(`**Timeout:** ${ir.constraints.timeoutMs}ms`);\n lines.push('');\n }\n if (ir.constraints.resourceLimits) {\n lines.push('### Resource Limits');\n lines.push('');\n if (ir.constraints.resourceLimits.memoryMb) {\n lines.push(`- Memory: ${ir.constraints.resourceLimits.memoryMb} MB`);\n }\n if (ir.constraints.resourceLimits.cpuCores) {\n lines.push(`- CPU: ${ir.constraints.resourceLimits.cpuCores} cores`);\n }\n lines.push('');\n }\n }\n\n // Errors\n if (ir.errors?.length) {\n lines.push('## Errors');\n lines.push('');\n lines.push('| Code | Description | Recovery |');\n lines.push('|------|-------------|----------|');\n for (const err of ir.errors) {\n lines.push(`| \\`${err.code}\\` | ${err.description ?? ''} | ${err.recovery ?? ''} |`);\n }\n lines.push('');\n }\n\n // Lifecycle\n if (ir.lifecycle?.deprecation) {\n lines.push('## Lifecycle');\n lines.push('');\n lines.push('> [!WARNING]');\n lines.push(`> This tool is deprecated as of ${ir.lifecycle.deprecation.deprecatedAt}.`);\n lines.push(`> Sunset date: ${ir.lifecycle.deprecation.sunsetDate}`);\n if (ir.lifecycle.deprecation.migrationUrl) {\n lines.push(`> Migration guide: ${ir.lifecycle.deprecation.migrationUrl}`);\n }\n lines.push('');\n }\n\n // Examples\n if (ir.narrative?.examples?.length) {\n lines.push('## Examples');\n lines.push('');\n for (const example of ir.narrative.examples) {\n if (example.title) {\n lines.push(`### ${example.title}`);\n lines.push('');\n }\n if (example.description) {\n lines.push(example.description);\n lines.push('');\n }\n if (example.input) {\n lines.push('**Input:**');\n lines.push('```json');\n lines.push(JSON.stringify(example.input, null, 2));\n lines.push('```');\n lines.push('');\n }\n if (example.output) {\n lines.push('**Output:**');\n lines.push('```json');\n lines.push(JSON.stringify(example.output, null, 2));\n lines.push('```');\n lines.push('');\n }\n }\n }\n\n // Notes\n if (ir.narrative?.notes?.length) {\n lines.push('## Notes');\n lines.push('');\n lines.push('*[author notes]*');\n lines.push('');\n for (const note of ir.narrative.notes) {\n lines.push(note);\n lines.push('');\n }\n }\n\n // Footer\n lines.push('---');\n lines.push('');\n lines.push(`*Generated at ${ir.generatedAt}* `);\n lines.push(`*Determinism key: \\`${ir.determinismKey}\\`*`);\n\n return lines.join('\\n');\n}\n\nfunction renderParameterTable(params: Parameter[]): string {\n const lines: string[] = [];\n lines.push('| Name | Type | Required | Default | Description |');\n lines.push('|------|------|----------|---------|-------------|');\n\n for (const param of params) {\n const required = param.required ? '✓' : '';\n const defaultVal = param.default !== undefined ? `\\`${JSON.stringify(param.default)}\\`` : '';\n const desc = param.description ?? '';\n lines.push(`| \\`${param.name}\\` | \\`${param.type}\\` | ${required} | ${defaultVal} | ${desc} |`);\n }\n\n return lines.join('\\n');\n}\n\nfunction provenanceBadge(source?: ProvenanceSource): string {\n if (!source) return '';\n const badges: Record<ProvenanceSource, string> = {\n introspection: '`[from introspection]`',\n manifest: '`[from schema]`',\n overlay: '`[from overlay]`',\n narrative: '`[author notes]`',\n };\n return badges[source] ?? '';\n}\n","import { marked } from 'marked';\nimport type { DocIR } from '../ir/types.js';\nimport { renderMarkdown } from './markdownRenderer.js';\n\n/**\n * Render Doc IR to static HTML\n */\nexport function renderHTML(ir: DocIR): string {\n // First render to markdown, then convert to HTML\n const markdown = renderMarkdown(ir);\n const htmlContent = marked.parse(markdown) as string;\n\n return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"light\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <meta name=\"description\" content=\"${escapeHtml(ir.entity.description ?? `Documentation for ${ir.entity.id}`)}\">\n <title>${escapeHtml(ir.entity.id)} - odd-docs</title>\n <style>\n${getThemeStyles()}\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <nav class=\"breadcrumb\">\n <a href=\"index.html\">Home</a> / <span>${escapeHtml(ir.entity.id)}</span>\n </nav>\n </header>\n <main class=\"content\">\n${htmlContent}\n </main>\n <footer>\n <p class=\"meta\">\n Generated by <a href=\"https://github.com/oddessentials/odd-docs\">odd-docs</a> at ${ir.generatedAt}\n </p>\n <p class=\"determinism\">\n <code>${ir.determinismKey}</code>\n </p>\n </footer>\n </div>\n <script>\n${getThemeScript()}\n </script>\n</body>\n</html>`;\n}\n\n/**\n * Generate index page for multiple docs\n */\nexport function renderIndexHTML(docs: DocIR[]): string {\n const items = docs\n .map(\n (ir) => `\n <li>\n <a href=\"${ir.entity.id}.html\">\n <strong>${escapeHtml(ir.entity.id)}</strong>\n <span class=\"version\">v${ir.entity.version}</span>\n </a>\n <p>${escapeHtml(ir.entity.description ?? '')}</p>\n </li>`\n )\n .join('\\n');\n\n return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"light\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Documentation - odd-docs</title>\n <style>\n${getThemeStyles()}\n </style>\n</head>\n<body>\n <div class=\"container\">\n <header>\n <h1>Documentation</h1>\n </header>\n <main class=\"content\">\n <ul class=\"doc-list\">\n${items}\n </ul>\n </main>\n <footer>\n <p class=\"meta\">Generated by <a href=\"https://github.com/oddessentials/odd-docs\">odd-docs</a></p>\n </footer>\n </div>\n <script>\n${getThemeScript()}\n </script>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(str: string): string {\n return str\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\nfunction getThemeStyles(): string {\n return `\n /* CSS Variables for theming */\n :root {\n /* Colors - neutral palette */\n --color-bg: #ffffff;\n --color-bg-secondary: #f8f9fa;\n --color-text: #1a1a2e;\n --color-text-muted: #6c757d;\n --color-border: #dee2e6;\n --color-link: #0066cc;\n --color-link-hover: #004499;\n --color-accent: #0066cc;\n --color-success: #28a745;\n --color-warning: #ffc107;\n --color-error: #dc3545;\n \n /* Typography */\n --font-sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;\n --font-mono: 'SF Mono', Monaco, 'Cascadia Code', monospace;\n --font-size-base: 16px;\n --line-height: 1.6;\n \n /* Spacing */\n --space-xs: 0.25rem;\n --space-sm: 0.5rem;\n --space-md: 1rem;\n --space-lg: 1.5rem;\n --space-xl: 2rem;\n \n /* Layout */\n --max-width: 800px;\n --border-radius: 4px;\n }\n \n [data-theme=\"dark\"] {\n --color-bg: #1a1a2e;\n --color-bg-secondary: #16213e;\n --color-text: #e8e8e8;\n --color-text-muted: #a0a0a0;\n --color-border: #3a3a5e;\n --color-link: #66b3ff;\n --color-link-hover: #99ccff;\n }\n \n /* Reset */\n *, *::before, *::after {\n box-sizing: border-box;\n }\n \n body {\n margin: 0;\n padding: 0;\n font-family: var(--font-sans);\n font-size: var(--font-size-base);\n line-height: var(--line-height);\n color: var(--color-text);\n background: var(--color-bg);\n }\n \n /* Container */\n .container {\n max-width: var(--max-width);\n margin: 0 auto;\n padding: var(--space-lg);\n }\n \n /* Typography */\n h1, h2, h3, h4, h5, h6 {\n margin-top: var(--space-xl);\n margin-bottom: var(--space-md);\n line-height: 1.3;\n }\n \n h1 { font-size: 2rem; }\n h2 { font-size: 1.5rem; border-bottom: 1px solid var(--color-border); padding-bottom: var(--space-sm); }\n h3 { font-size: 1.25rem; }\n \n p { margin: var(--space-md) 0; }\n \n a {\n color: var(--color-link);\n text-decoration: none;\n }\n \n a:hover {\n color: var(--color-link-hover);\n text-decoration: underline;\n }\n \n /* Code */\n code {\n font-family: var(--font-mono);\n font-size: 0.9em;\n background: var(--color-bg-secondary);\n padding: var(--space-xs) var(--space-sm);\n border-radius: var(--border-radius);\n }\n \n pre {\n background: var(--color-bg-secondary);\n padding: var(--space-md);\n border-radius: var(--border-radius);\n overflow-x: auto;\n }\n \n pre code {\n background: none;\n padding: 0;\n }\n \n /* Tables */\n table {\n width: 100%;\n border-collapse: collapse;\n margin: var(--space-md) 0;\n }\n \n th, td {\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n text-align: left;\n }\n \n th {\n background: var(--color-bg-secondary);\n font-weight: 600;\n }\n \n /* Provenance badges */\n code[class*=\"from\"] {\n font-size: 0.75em;\n color: var(--color-text-muted);\n background: transparent;\n }\n \n /* Blockquotes (for warnings/notes) */\n blockquote {\n margin: var(--space-md) 0;\n padding: var(--space-md);\n border-left: 4px solid var(--color-warning);\n background: var(--color-bg-secondary);\n }\n \n blockquote p:first-child { margin-top: 0; }\n blockquote p:last-child { margin-bottom: 0; }\n \n /* Lists */\n ul, ol {\n padding-left: var(--space-lg);\n }\n \n li { margin: var(--space-sm) 0; }\n \n /* Doc list (index page) */\n .doc-list {\n list-style: none;\n padding: 0;\n }\n \n .doc-list li {\n padding: var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--border-radius);\n margin-bottom: var(--space-md);\n }\n \n .doc-list a {\n display: flex;\n align-items: center;\n gap: var(--space-sm);\n }\n \n .doc-list .version {\n color: var(--color-text-muted);\n font-size: 0.875em;\n }\n \n .doc-list p {\n margin: var(--space-sm) 0 0;\n color: var(--color-text-muted);\n }\n \n /* Header */\n header {\n margin-bottom: var(--space-lg);\n }\n \n .breadcrumb {\n font-size: 0.875em;\n color: var(--color-text-muted);\n }\n \n .breadcrumb a {\n color: inherit;\n }\n \n /* Footer */\n footer {\n margin-top: var(--space-xl);\n padding-top: var(--space-lg);\n border-top: 1px solid var(--color-border);\n font-size: 0.875em;\n color: var(--color-text-muted);\n }\n \n .determinism code {\n font-size: 0.75em;\n }\n \n /* Theme toggle */\n .theme-toggle {\n position: fixed;\n top: var(--space-md);\n right: var(--space-md);\n padding: var(--space-sm) var(--space-md);\n border: 1px solid var(--color-border);\n border-radius: var(--border-radius);\n background: var(--color-bg);\n cursor: pointer;\n font-size: 0.875em;\n }\n \n /* Responsive */\n @media (max-width: 600px) {\n .container { padding: var(--space-md); }\n h1 { font-size: 1.5rem; }\n h2 { font-size: 1.25rem; }\n table { font-size: 0.875em; }\n }\n `;\n}\n\nfunction getThemeScript(): string {\n return `\n // Theme toggle\n const toggle = document.createElement('button');\n toggle.className = 'theme-toggle';\n toggle.textContent = '🌙';\n toggle.onclick = () => {\n const html = document.documentElement;\n const isDark = html.dataset.theme === 'dark';\n html.dataset.theme = isDark ? 'light' : 'dark';\n toggle.textContent = isDark ? '🌙' : '☀️';\n localStorage.setItem('theme', html.dataset.theme);\n };\n document.body.appendChild(toggle);\n \n // Restore saved theme\n const saved = localStorage.getItem('theme');\n if (saved) {\n document.documentElement.dataset.theme = saved;\n toggle.textContent = saved === 'dark' ? '☀️' : '🌙';\n } else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {\n document.documentElement.dataset.theme = 'dark';\n toggle.textContent = '☀️';\n }\n `;\n}\n","import { resolve } from 'node:path';\nimport { parseManifest } from '../../core/parser/manifestParser.js';\nimport { buildDocIR } from '../../core/ir/builder.js';\nimport { validateDocIR, formatValidationResult } from '../../core/ir/validator.js';\n\nexport interface ValidateOptions {\n strict?: boolean;\n}\n\nexport async function validate(repoPath: string, options: ValidateOptions = {}): Promise<boolean> {\n const absPath = resolve(repoPath);\n\n console.log(`Validating: ${absPath}`);\n console.log(`Mode: ${options.strict ? 'strict' : 'normal'}`);\n console.log('');\n\n try {\n // Parse manifest\n const manifestResult = await parseManifest(absPath);\n\n // Build Doc IR\n const ir = buildDocIR(manifestResult);\n\n // Validate\n const result = validateDocIR(ir, { strict: options.strict });\n\n // Format and print result\n console.log(formatValidationResult(result, absPath));\n\n return result.valid;\n } catch (error) {\n console.error('✗ Validation failed');\n console.error('');\n console.error(`Error: ${error instanceof Error ? error.message : error}`);\n return false;\n }\n}\n","/**\n * Known capabilities allowlist\n * Safety-affecting capabilities trigger stricter validation\n */\n\nexport const KNOWN_CAPABILITIES = [\n 'network',\n 'filesystem',\n 'secrets',\n 'exec',\n 'subprocess',\n 'database',\n 'queue',\n] as const;\n\nexport type KnownCapability = (typeof KNOWN_CAPABILITIES)[number];\n\n/**\n * Capabilities that imply safety-critical operations\n * Unknown capabilities matching these patterns fail in --strict mode\n */\nexport const SAFETY_AFFECTING_PATTERNS = ['network', 'exec', 'subprocess', 'write', 'delete'];\n\nexport function isKnownCapability(capability: string): capability is KnownCapability {\n return KNOWN_CAPABILITIES.includes(capability as KnownCapability);\n}\n\nexport function isSafetyAffecting(capability: string): boolean {\n return SAFETY_AFFECTING_PATTERNS.some((pattern) =>\n capability.toLowerCase().includes(pattern.toLowerCase())\n );\n}\n","import type { DocIR, ProvenanceSource } from '../ir/types.js';\nimport { isKnownCapability, isSafetyAffecting } from '../capabilities.js';\n\nexport type ValidationSeverity = 'error' | 'warning';\n\nexport interface ValidationIssue {\n severity: ValidationSeverity;\n code: string;\n message: string;\n path?: string;\n provenance?: ProvenanceSource;\n}\n\nexport interface ValidationResult {\n valid: boolean;\n issues: ValidationIssue[];\n}\n\nexport interface ValidateOptions {\n strict?: boolean;\n}\n\n/**\n * Validate Doc IR for completeness and consistency\n */\nexport function validateDocIR(ir: DocIR, options: ValidateOptions = {}): ValidationResult {\n const issues: ValidationIssue[] = [];\n\n // Required field checks\n if (!ir.entity.id) {\n issues.push({\n severity: 'error',\n code: 'MISSING_TOOL_ID',\n message: 'Tool ID is required',\n path: 'entity.id',\n });\n }\n\n if (!ir.entity.version) {\n issues.push({\n severity: 'error',\n code: 'MISSING_VERSION',\n message: 'Version is required',\n path: 'entity.version',\n });\n }\n\n if (!ir.inputs?.schema && !ir.inputs?.parameters?.length) {\n issues.push({\n severity: 'error',\n code: 'MISSING_PARAMETERS_SCHEMA',\n message: 'Parameters schema is required',\n path: 'inputs',\n });\n }\n\n // Capability validation\n if (ir.constraints?.capabilities) {\n for (const cap of ir.constraints.capabilities) {\n if (!isKnownCapability(cap.type)) {\n const isSafety = isSafetyAffecting(cap.type);\n issues.push({\n severity: options.strict && isSafety ? 'error' : 'warning',\n code: 'UNKNOWN_CAPABILITY',\n message: `Unknown capability: ${cap.type}${isSafety ? ' (safety-affecting)' : ''}`,\n path: `constraints.capabilities.${cap.type}`,\n provenance: cap.provenance,\n });\n }\n }\n }\n\n // Structural contradiction checks\n issues.push(...checkStructuralContradictions(ir));\n\n const hasErrors = issues.some((i) => i.severity === 'error');\n\n return {\n valid: !hasErrors,\n issues,\n };\n}\n\n/**\n * Check for structural contradictions between sources\n */\nfunction checkStructuralContradictions(ir: DocIR): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n // Check if narrative mentions parameters not in schema\n if (ir.narrative?.notes && ir.inputs?.parameters) {\n const schemaParams = new Set(ir.inputs.parameters.map((p) => p.name.toLowerCase()));\n\n for (const note of ir.narrative.notes) {\n // Match patterns like \"parameter X\" or \"the X parameter\"\n const paramMentions = note.match(/(?:parameter|param)\\s+[`\"']?(\\w+)[`\"']?/gi) ?? [];\n const theParamMentions = note.match(/the\\s+[`\"']?(\\w+)[`\"']?\\s+parameter/gi) ?? [];\n\n for (const match of [...paramMentions, ...theParamMentions]) {\n const paramName = match.replace(/.*?[`\"']?(\\w+)[`\"']?.*/i, '$1').toLowerCase();\n if (paramName && !schemaParams.has(paramName) && paramName !== 'parameter') {\n issues.push({\n severity: 'error',\n code: 'NARRATIVE_REFERENCES_UNDEFINED_PARAM',\n message: `Narrative references parameter \"${paramName}\" not in schema`,\n path: 'narrative.notes',\n provenance: 'narrative',\n });\n }\n }\n }\n }\n\n // Check if examples use parameters not in schema\n if (ir.narrative?.examples && ir.inputs?.parameters) {\n const schemaParams = new Set(ir.inputs.parameters.map((p) => p.name));\n\n for (const example of ir.narrative.examples) {\n if (example.input && typeof example.input === 'object') {\n for (const key of Object.keys(example.input as Record<string, unknown>)) {\n if (!schemaParams.has(key)) {\n issues.push({\n severity: 'warning',\n code: 'EXAMPLE_USES_UNDEFINED_PARAM',\n message: `Example uses parameter \"${key}\" not in schema`,\n path: `narrative.examples.${example.title ?? 'unnamed'}`,\n provenance: 'narrative',\n });\n }\n }\n }\n }\n }\n\n // Check for side effect / capability contradictions\n if (ir.overview?.sideEffects && ir.constraints?.capabilities) {\n const capTypes = new Set(ir.constraints.capabilities.map((c) => c.type));\n\n for (const effect of ir.overview.sideEffects) {\n // Map side effect types to capability types\n const expectedCap = mapSideEffectToCapability(effect.type);\n if (expectedCap && !capTypes.has(expectedCap)) {\n issues.push({\n severity: 'error',\n code: 'SIDE_EFFECT_CAPABILITY_MISMATCH',\n message: `Side effect \"${effect.type}\" requires capability \"${expectedCap}\" which is not declared`,\n path: `overview.sideEffects.${effect.type}`,\n provenance: effect.provenance,\n });\n }\n }\n }\n\n return issues;\n}\n\nfunction mapSideEffectToCapability(effectType: string): string | null {\n const mapping: Record<string, string> = {\n filesystem: 'filesystem',\n network: 'network',\n secrets: 'secrets',\n exec: 'exec',\n subprocess: 'subprocess',\n database: 'database',\n queue: 'queue',\n };\n return mapping[effectType] ?? null;\n}\n\n/**\n * Format validation result for CLI output\n */\nexport function formatValidationResult(result: ValidationResult, repoPath: string): string {\n const lines: string[] = [];\n\n lines.push(`Validating: ${repoPath}`);\n lines.push('');\n\n if (result.valid) {\n lines.push('✓ Validation passed');\n } else {\n lines.push('✗ Validation failed');\n }\n lines.push('');\n\n const errors = result.issues.filter((i) => i.severity === 'error');\n const warnings = result.issues.filter((i) => i.severity === 'warning');\n\n if (errors.length > 0) {\n lines.push(`Errors (${errors.length}):`);\n for (const issue of errors) {\n lines.push(` ✗ [${issue.code}] ${issue.message}`);\n if (issue.path) {\n lines.push(` at ${issue.path}`);\n }\n }\n lines.push('');\n }\n\n if (warnings.length > 0) {\n lines.push(`Warnings (${warnings.length}):`);\n for (const issue of warnings) {\n lines.push(` ⚠ [${issue.code}] ${issue.message}`);\n if (issue.path) {\n lines.push(` at ${issue.path}`);\n }\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","/**\n * Serve Command\n *\n * Start a local development server for generated documentation.\n * Enforces safe defaults per deployment stance:\n * - localhost binding\n * - mutations disabled\n * - SSE auto-switch for non-localhost\n */\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { OddDocsServer, type ServeOptions } from '../../server/index.js';\nimport { generate } from './generate.js';\n\nexport interface ServeCommandOptions {\n port?: number;\n host?: string;\n output?: string;\n watch?: boolean;\n watchMode?: 'auto' | 'poll';\n reload?: 'ws' | 'sse' | 'poll' | 'none';\n open?: boolean;\n introspect?: string;\n enableMutations?: boolean;\n mutationToken?: string;\n}\n\n/**\n * Serve documentation with live reload\n */\nexport async function serve(repoPath: string, options: ServeCommandOptions = {}): Promise<void> {\n const resolvedPath = resolve(repoPath);\n\n // Determine output directory\n const outputDir = options.output\n ? resolve(options.output)\n : join(resolvedPath, 'docs', 'generated');\n\n // Check if docs exist, generate if not\n if (!existsSync(outputDir)) {\n console.log('[odd-docs] Documentation not found, generating...');\n await generate(repoPath, { output: outputDir, format: 'html' });\n }\n\n // Determine reload mode\n let reloadMode: 'ws' | 'sse' | 'poll' | 'none' = options.reload ?? 'ws';\n\n // Use poll mode if explicitly requested via env or option\n if (options.watchMode === 'poll' || process.env.CHOKIDAR_USEPOLLING === '1') {\n reloadMode = 'poll';\n console.log('[odd-docs] Using poll-based watching (CPU intensive)');\n }\n\n const host = options.host ?? 'localhost';\n const port = options.port ?? 3000;\n\n // Auto-switch to SSE for non-localhost (safer for K8s)\n if (host !== 'localhost' && options.reload === undefined) {\n reloadMode = 'sse';\n console.log('[odd-docs] Using SSE for non-localhost binding');\n }\n\n // Create and start server\n const serverOptions: Partial<ServeOptions> & { outputDir: string } = {\n outputDir,\n host,\n port,\n watch: options.watch !== false,\n reloadMode,\n enableMutations: options.enableMutations ?? false,\n mutationToken: options.mutationToken,\n };\n\n const server = new OddDocsServer(serverOptions);\n\n // Handle shutdown\n const shutdown = async () => {\n console.log('\\n[odd-docs] Shutting down...');\n await server.stop();\n process.exit(0);\n };\n\n process.on('SIGINT', shutdown);\n process.on('SIGTERM', shutdown);\n\n try {\n await server.start();\n\n // Open browser if requested\n if (options.open !== false && host === 'localhost') {\n const url = `http://${host}:${port}`;\n try {\n const { default: open } = await import('open');\n await open(url);\n } catch {\n console.log(`[odd-docs] Open browser manually: ${url}`);\n }\n }\n } catch (error) {\n console.error('[odd-docs] Failed to start server:', error);\n process.exit(1);\n }\n}\n","/**\n * OddDocs Server\n *\n * HTTP server wrapper for serving generated documentation.\n * Enforces safe defaults: localhost binding, no mutations without explicit opt-in.\n */\n\nimport { createServer, type Server, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { FileServer } from './fileServer.js';\nimport { LiveReload } from './livereload.js';\nimport { ApiHandler, type ServerState } from './api.js';\n\nexport interface ServeOptions {\n /** Port to listen on. Default: 3000 */\n port: number;\n /** Host to bind. Default: 'localhost' (safe) */\n host: string;\n /** Documentation output directory */\n outputDir: string;\n /** Enable file watching for live reload. Default: true */\n watch: boolean;\n /** Reload mechanism. Default: 'ws' for localhost, 'sse' for 0.0.0.0 */\n reloadMode: 'ws' | 'sse' | 'poll' | 'none';\n /** Enable mutation API endpoints. Default: false */\n enableMutations: boolean;\n /** Token for mutation endpoints. Required if enableMutations=true */\n mutationToken?: string;\n /** Request timeout in ms. Default: 30000 */\n requestTimeout: number;\n}\n\nexport const DEFAULT_OPTIONS: Omit<ServeOptions, 'outputDir'> = {\n port: 3000,\n host: 'localhost',\n watch: true,\n reloadMode: 'ws',\n enableMutations: false,\n requestTimeout: 30000,\n};\n\nexport class OddDocsServer {\n private server: Server | null = null;\n private fileServer: FileServer;\n private liveReload: LiveReload | null = null;\n private apiHandler: ApiHandler;\n private options: ServeOptions;\n private state: ServerState;\n\n constructor(options: Partial<ServeOptions> & { outputDir: string }) {\n // Apply defaults\n this.options = {\n ...DEFAULT_OPTIONS,\n ...options,\n // Auto-switch to SSE for non-localhost binding (safer for K8s)\n reloadMode:\n options.reloadMode ??\n (options.host && options.host !== 'localhost' ? 'sse' : DEFAULT_OPTIONS.reloadMode),\n };\n\n // Environment overrides\n this.options.host = process.env.ODD_DOCS_HOST ?? this.options.host;\n this.options.port = parseInt(process.env.ODD_DOCS_PORT ?? String(this.options.port), 10);\n this.options.mutationToken = process.env.ODD_DOCS_MUTATION_TOKEN ?? this.options.mutationToken;\n\n this.state = {\n lastGenerateSuccess: true,\n lastGenerateTime: new Date().toISOString(),\n outputDirAccessible: true,\n introspectionConnected: false,\n };\n\n this.fileServer = new FileServer(this.options.outputDir);\n this.apiHandler = new ApiHandler(this.state, this.options);\n }\n\n async start(): Promise<void> {\n // Validate mutation token if mutations enabled\n if (this.options.enableMutations && !this.options.mutationToken) {\n throw new Error(\n 'Mutation token required when --enable-mutations is set. ' +\n 'Set ODD_DOCS_MUTATION_TOKEN or --mutation-token'\n );\n }\n\n this.server = createServer((req, res) => this.handleRequest(req, res));\n\n // Set timeout\n this.server.timeout = this.options.requestTimeout;\n\n // Start live reload if enabled\n if (this.options.watch && this.options.reloadMode !== 'none') {\n this.liveReload = new LiveReload({\n outputDir: this.options.outputDir,\n mode: this.options.reloadMode,\n server: this.server,\n });\n await this.liveReload.start();\n }\n\n return new Promise((resolve, reject) => {\n this.server!.listen(this.options.port, this.options.host, () => {\n console.log(\n `[odd-docs] Server started at http://${this.options.host}:${this.options.port}`\n );\n console.log(`[odd-docs] Serving: ${this.options.outputDir}`);\n if (this.liveReload) {\n console.log(`[odd-docs] Live reload: ${this.options.reloadMode}`);\n }\n resolve();\n });\n\n this.server!.on('error', reject);\n });\n }\n\n async stop(): Promise<void> {\n if (this.liveReload) {\n await this.liveReload.stop();\n }\n if (this.server) {\n return new Promise((resolve) => {\n this.server!.close(() => resolve());\n });\n }\n }\n\n private async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = req.url ?? '/';\n\n try {\n // API routes\n if (url.startsWith('/api/')) {\n await this.apiHandler.handle(req, res);\n return;\n }\n\n // Live reload endpoints\n if (this.liveReload && url === '/__livereload') {\n await this.liveReload.handleRequest(req, res);\n return;\n }\n\n // Static file serving\n await this.fileServer.serve(req, res);\n } catch (error) {\n console.error('[odd-docs] Request error:', error);\n res.statusCode = 500;\n res.end('Internal Server Error');\n }\n }\n\n updateState(updates: Partial<ServerState>): void {\n Object.assign(this.state, updates);\n }\n}\n","/**\n * File Server\n *\n * Static file serving with security protections.\n * - Path traversal protection via realpath + relative check\n * - MIME type detection\n * - ETag/304 support\n * - Max response size cap\n */\n\nimport { createReadStream, statSync } from 'node:fs';\nimport { realpath } from 'node:fs/promises';\nimport { join, extname, relative, isAbsolute } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nconst MAX_RESPONSE_SIZE = 50 * 1024 * 1024; // 50MB\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.md': 'text/markdown; charset=utf-8',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.svg': 'image/svg+xml',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.ttf': 'font/ttf',\n};\n\nexport class FileServer {\n private rootDir: string;\n private resolvedRoot: string | null = null;\n\n constructor(rootDir: string) {\n this.rootDir = rootDir;\n }\n\n async serve(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n let pathname = decodeURIComponent(url.pathname);\n\n // Default to index.html\n if (pathname === '/' || pathname.endsWith('/')) {\n pathname = join(pathname, 'index.html');\n }\n\n // Resolve and validate path\n const filePath = await this.resolvePath(pathname);\n if (!filePath) {\n res.statusCode = 403;\n res.end('Forbidden: Path traversal blocked');\n return;\n }\n\n // Check file exists and get stats\n let stats;\n try {\n stats = statSync(filePath);\n } catch {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n\n if (!stats.isFile()) {\n res.statusCode = 404;\n res.end('Not Found');\n return;\n }\n\n // Check size limit\n if (stats.size > MAX_RESPONSE_SIZE) {\n res.statusCode = 413;\n res.end('File too large');\n return;\n }\n\n // ETag handling\n const etag = this.computeETag(filePath, stats.mtime, stats.size);\n const ifNoneMatch = req.headers['if-none-match'];\n if (ifNoneMatch === etag) {\n res.statusCode = 304;\n res.end();\n return;\n }\n\n // Set headers\n const ext = extname(filePath).toLowerCase();\n const contentType = MIME_TYPES[ext] ?? 'application/octet-stream';\n\n res.setHeader('Content-Type', contentType);\n res.setHeader('Content-Length', stats.size);\n res.setHeader('ETag', etag);\n res.setHeader('Cache-Control', 'no-cache');\n\n // Stream file\n const stream = createReadStream(filePath);\n stream.pipe(res);\n stream.on('error', () => {\n res.statusCode = 500;\n res.end('Error reading file');\n });\n }\n\n /**\n * Resolve path with traversal protection\n */\n private async resolvePath(pathname: string): Promise<string | null> {\n // Ensure we have the real root path\n if (!this.resolvedRoot) {\n try {\n this.resolvedRoot = await realpath(this.rootDir);\n } catch {\n return null;\n }\n }\n\n // Construct target path\n const targetPath = join(this.rootDir, pathname);\n\n // Resolve to real path (follows symlinks, canonicalizes)\n let resolvedTarget: string;\n try {\n resolvedTarget = await realpath(targetPath);\n } catch {\n return null;\n }\n\n // Check containment: resolved path must be within root\n const rel = relative(this.resolvedRoot, resolvedTarget);\n if (rel.startsWith('..') || isAbsolute(rel)) {\n // Path escapes root directory\n console.warn(`[odd-docs] Path traversal blocked: ${pathname}`);\n return null;\n }\n\n return resolvedTarget;\n }\n\n private computeETag(path: string, mtime: Date, size: number): string {\n const hash = createHash('md5')\n .update(`${path}:${mtime.getTime()}:${size}`)\n .digest('hex')\n .slice(0, 16);\n return `\"${hash}\"`;\n }\n}\n","/**\n * Live Reload\n *\n * File watching and live reload for development.\n * Supports multiple mechanisms: WebSocket, SSE, Polling.\n * WS is dev-only default; SSE is K8s-safe.\n */\n\nimport { watch, type FSWatcher } from 'node:fs';\nimport type { Server, IncomingMessage, ServerResponse } from 'node:http';\n\nexport interface LiveReloadOptions {\n outputDir: string;\n mode: 'ws' | 'sse' | 'poll' | 'none';\n server: Server;\n pollInterval?: number; // for poll mode, ms\n}\n\ntype ReloadMode = 'ws' | 'sse' | 'poll' | 'none';\n\nexport class LiveReload {\n private options: LiveReloadOptions;\n private watcher: FSWatcher | null = null;\n private sseClients: Set<ServerResponse> = new Set();\n private lastChangeTime: number = Date.now();\n private debounceTimer: NodeJS.Timeout | null = null;\n\n constructor(options: LiveReloadOptions) {\n this.options = {\n pollInterval: 5000,\n ...options,\n };\n }\n\n async start(): Promise<void> {\n // Start file watcher with debounce\n const usePolling = process.env.CHOKIDAR_USEPOLLING === '1' || this.options.mode === 'poll';\n\n this.watcher = watch(\n this.options.outputDir,\n { recursive: true, persistent: true },\n (_eventType, filename) => {\n if (filename) {\n this.onFileChange(filename);\n }\n }\n );\n\n if (usePolling) {\n console.log('[odd-docs] Using poll-based file watching');\n }\n\n console.log(`[odd-docs] Live reload started (mode: ${this.options.mode})`);\n }\n\n async stop(): Promise<void> {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n if (this.watcher) {\n this.watcher.close();\n }\n // Close SSE connections\n for (const client of this.sseClients) {\n client.end();\n }\n this.sseClients.clear();\n }\n\n private onFileChange(filename: string): void {\n // Debounce rapid changes\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n }\n this.debounceTimer = setTimeout(() => {\n this.lastChangeTime = Date.now();\n console.log(`[odd-docs] Change detected: ${filename}`);\n this.notifyClients();\n }, 100);\n }\n\n private notifyClients(): void {\n const message = JSON.stringify({ type: 'reload', time: this.lastChangeTime });\n\n // Notify SSE clients\n for (const client of this.sseClients) {\n client.write(`data: ${message}\\n\\n`);\n }\n }\n\n async handleRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const mode = this.options.mode;\n\n if (mode === 'sse') {\n // SSE endpoint\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no'); // For nginx\n\n res.write(': ping\\n\\n');\n this.sseClients.add(res);\n\n req.on('close', () => {\n this.sseClients.delete(res);\n });\n } else if (mode === 'poll') {\n // Poll endpoint - return last change time\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify({ lastChange: this.lastChangeTime }));\n } else {\n // Not supported in this mode\n res.statusCode = 404;\n res.end('Live reload not available in this mode');\n }\n }\n\n /**\n * Get client-side script for live reload\n */\n static getClientScript(mode: ReloadMode, pollInterval: number = 5000): string {\n if (mode === 'none') return '';\n\n if (mode === 'sse') {\n return `\n<script>\n(function() {\n const es = new EventSource('/__livereload');\n es.onmessage = function(e) {\n const data = JSON.parse(e.data);\n if (data.type === 'reload') {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n };\n es.onerror = function() {\n console.log('[odd-docs] SSE connection lost, will retry...');\n };\n})();\n</script>`;\n }\n\n if (mode === 'poll') {\n return `\n<script>\n(function() {\n let lastChange = 0;\n setInterval(async () => {\n try {\n const res = await fetch('/__livereload');\n const data = await res.json();\n if (lastChange && data.lastChange > lastChange) {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n lastChange = data.lastChange;\n } catch (e) {}\n }, ${pollInterval});\n})();\n</script>`;\n }\n\n // WebSocket (ws mode) - requires separate ws server\n return `\n<script>\n(function() {\n const ws = new WebSocket('ws://' + location.host + '/__ws');\n ws.onmessage = function(e) {\n const data = JSON.parse(e.data);\n if (data.type === 'reload') {\n console.log('[odd-docs] Reloading...');\n location.reload();\n }\n };\n ws.onclose = function() {\n console.log('[odd-docs] WebSocket closed, will retry in 3s...');\n setTimeout(() => location.reload(), 3000);\n };\n})();\n</script>`;\n }\n}\n","/**\n * API Handler\n *\n * REST API endpoints for programmatic access.\n * Implements K8s-compatible health semantics.\n * Mutation endpoints require explicit opt-in + token.\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { ServeOptions } from './index.js';\n\nconst MAX_IR_SIZE = 10 * 1024 * 1024; // 10MB\n\nexport interface ServerState {\n lastGenerateSuccess: boolean;\n lastGenerateTime: string;\n outputDirAccessible: boolean;\n introspectionConnected: boolean;\n lastIntrospectionTime?: string;\n}\n\nexport class ApiHandler {\n private state: ServerState;\n private options: ServeOptions;\n\n constructor(state: ServerState, options: ServeOptions) {\n this.state = state;\n this.options = options;\n }\n\n async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const url = new URL(req.url ?? '/', `http://${req.headers.host}`);\n const path = url.pathname;\n const method = req.method ?? 'GET';\n\n // Route to handlers\n switch (path) {\n case '/api/health':\n return this.handleHealth(res);\n case '/api/ready':\n return this.handleReady(res);\n case '/api/introspection':\n return this.handleIntrospection(res);\n case '/api/docs':\n return this.handleDocs(res);\n case '/api/ir':\n return this.handleIR(res);\n case '/api/capabilities':\n return this.handleCapabilities(res);\n case '/api/regenerate':\n if (method === 'POST') {\n return this.handleRegenerate(req, res);\n }\n return this.methodNotAllowed(res);\n default:\n return this.notFound(res);\n }\n }\n\n /**\n * GET /api/health - Liveness probe\n * Returns 200 if process is running\n */\n private handleHealth(res: ServerResponse): void {\n this.json(res, {\n status: 'ok',\n timestamp: new Date().toISOString(),\n });\n }\n\n /**\n * GET /api/ready - Readiness probe\n * Returns 200 if last generate succeeded and output is accessible\n */\n private handleReady(res: ServerResponse): void {\n const ready = this.state.lastGenerateSuccess && this.state.outputDirAccessible;\n\n if (!ready) {\n res.statusCode = 503;\n }\n\n this.json(res, {\n ready,\n lastGenerateSuccess: this.state.lastGenerateSuccess,\n lastGenerateTime: this.state.lastGenerateTime,\n outputDirAccessible: this.state.outputDirAccessible,\n });\n }\n\n /**\n * GET /api/introspection - Introspection status\n */\n private handleIntrospection(res: ServerResponse): void {\n this.json(res, {\n connected: this.state.introspectionConnected,\n lastPollTime: this.state.lastIntrospectionTime ?? null,\n });\n }\n\n /**\n * GET /api/docs - List documentation sections\n */\n private handleDocs(res: ServerResponse): void {\n // TODO: Implement actual doc listing\n this.json(res, {\n sections: [],\n message: 'Not implemented yet',\n });\n }\n\n /**\n * GET /api/ir - Full IR dump (capped at 10MB)\n */\n private handleIR(res: ServerResponse): void {\n // TODO: Implement actual IR retrieval\n const ir = { tools: [], prompts: [], resources: [] };\n const irJson = JSON.stringify(ir);\n\n if (irJson.length > MAX_IR_SIZE) {\n this.json(res, {\n truncated: true,\n message: `IR exceeds ${MAX_IR_SIZE / 1024 / 1024}MB limit`,\n partial: null,\n });\n return;\n }\n\n res.setHeader('Content-Type', 'application/json');\n res.end(irJson);\n }\n\n /**\n * GET /api/capabilities - Tool capabilities summary\n */\n private handleCapabilities(res: ServerResponse): void {\n this.json(res, {\n serve: {\n host: this.options.host,\n port: this.options.port,\n reloadMode: this.options.reloadMode,\n mutationsEnabled: this.options.enableMutations,\n },\n });\n }\n\n /**\n * POST /api/regenerate - Trigger manual regeneration\n * Requires --enable-mutations and valid token\n */\n private handleRegenerate(req: IncomingMessage, res: ServerResponse): void {\n // Check if mutations are enabled\n if (!this.options.enableMutations) {\n res.statusCode = 403;\n this.json(res, {\n error: 'Mutations disabled',\n message: 'Start server with --enable-mutations to use this endpoint',\n });\n return;\n }\n\n // Validate token\n const token = req.headers['x-mutation-token'];\n if (token !== this.options.mutationToken) {\n res.statusCode = 401;\n this.json(res, {\n error: 'Unauthorized',\n message: 'Invalid or missing X-Mutation-Token header',\n });\n return;\n }\n\n // TODO: Trigger actual regeneration\n this.json(res, {\n status: 'queued',\n message: 'Regeneration triggered',\n timestamp: new Date().toISOString(),\n });\n }\n\n private json(res: ServerResponse, data: unknown): void {\n res.setHeader('Content-Type', 'application/json');\n res.end(JSON.stringify(data, null, 2));\n }\n\n private notFound(res: ServerResponse): void {\n res.statusCode = 404;\n this.json(res, { error: 'Not Found' });\n }\n\n private methodNotAllowed(res: ServerResponse): void {\n res.statusCode = 405;\n this.json(res, { error: 'Method Not Allowed' });\n }\n}\n"],"mappings":"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","names":["join","join","resolve","resolve","join","resolve","join","createHash","resolve","resolve","join","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oddessentials/odd-docs",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "MCP-native documentation generator for clients, servers, and tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",