const { basename, dirname, resolve } = require('node:path'); const { existsSync } = require('node:fs'); const DOC_SEARCH_SUBDIRS = [ 'getting-started', 'architecture', 'features', 'memory', 'safety', 'observability', 'extensions', 'orchestration', ]; const SECTION_ORDER = [ 'Getting Started', 'Concepts', 'Architecture', 'Cognitive Pipeline', 'Memory', 'RAG & Retrieval', 'Text Processing & Search', 'Personas', 'Orchestration', 'Tools & Capabilities', 'Model Quality & Cost', 'Voice & Speech', 'Media Generation', 'Channels & Social', 'Guardrails & Safety', 'Provenance', 'Skills', 'Extensions', 'Benchmarks', 'Paracosm', 'Wunderland', 'Contributing', ]; function entry(config) { return config; } function agentosDoc(sourcePath, dest, title, section, position, extra = {}) { return entry({ sourceType: 'canonical-guide', sourcePath: `packages/agentos/docs/${sourcePath}`, dest, title, section, position, ...extra, }); } function extensionDoc(sourcePath, dest, title, position, extra = {}) { return entry({ sourceType: 'extension-guide', sourcePath: `packages/agentos-extensions/${sourcePath}`, dest, title, section: 'Extensions', position, ...extra, }); } function builtInExtension(dir, dest, title, position, extra = {}) { const sourceType = extra.allowMissingSource ? 'generated-stub' : 'built-in-extension'; return entry({ sourceType, sourcePath: `packages/agentos-extensions/registry/curated/${dir}/README.md`, dest, title, section: 'Extensions', position, group: extra.group ?? 'Official Extensions', ...extra, }); } function extraDoc(sourcePath, dest, title, section, position, extra = {}) { return entry({ sourceType: 'repo-doc', sourcePath, dest, title, section, position, ...extra, }); } function siteDoc(sourcePath, dest, title, section, position, extra = {}) { return entry({ sourceType: 'live-doc', sourcePath: `apps/agentos-live-docs/docs/${sourcePath}`, dest, title, section, position, ...extra, }); } function staticDoc(sourcePath, dest, title, section, position, extra = {}) { return entry({ sourceType: 'static-doc', sourcePath: `apps/agentos-live-docs/static-docs/${sourcePath}`, dest, title, section, position, ...extra, }); } const publicationManifest = [ agentosDoc('README.md', 'getting-started/documentation-index.md', 'Documentation Index', 'Getting Started', 1, { sidebar: false, }), agentosDoc('GETTING_STARTED.md', 'getting-started/index.md', 'Getting Started Guide', 'Getting Started', 2, { categoryIndex: true, }), agentosDoc('HIGH_LEVEL_API.md', 'getting-started/high-level-api.md', 'High-Level API', 'Getting Started', 3), agentosDoc('EXAMPLES.md', 'getting-started/examples.md', 'Examples Cookbook', 'Getting Started', 4), agentosDoc('ECOSYSTEM.md', 'getting-started/ecosystem.md', 'Ecosystem', 'Getting Started', 5), agentosDoc('RELEASING.md', 'getting-started/releasing.md', 'Releasing', 'Getting Started', 6), siteDoc('benchmarks/index.md', 'benchmarks/index.md', 'Memory Benchmarks', 'Benchmarks', 1, { categoryIndex: true, }), agentosDoc('evaluation/GMI_VS_AGENT.md', 'benchmarks/gmi-vs-agent.md', 'GMI versus agent() Study', 'Benchmarks', 2), agentosDoc('ARCHITECTURE.md', 'architecture/system-architecture.md', 'System Architecture', 'Concepts', 1), agentosDoc('GMI.md', 'architecture/gmi.md', 'Generalized Mind Instances (GMIs)', 'Concepts', 0.5), agentosDoc('API_PATHS.md', 'architecture/api-paths.md', 'Two API Paths: Lightweight Agents and the Runtime', 'Concepts', 0.7), agentosDoc('TURN_LIFECYCLE.md', 'architecture/turn-lifecycle.md', 'The Turn Lifecycle', 'Concepts', 1.2), agentosDoc('MEMORY_MODEL.md', 'architecture/memory-model.md', 'Memory Model', 'Concepts', 1.4), agentosDoc('SELF_EXTENSION.md', 'architecture/self-extension.md', 'Self-Extension: Forging and Self-Improvement', 'Concepts', 1.6), agentosDoc('AGENCIES.md', 'architecture/agencies.md', 'Agencies and Orchestration Strategies', 'Concepts', 1.8), agentosDoc('PLATFORM_SUPPORT.md', 'architecture/platform-support.md', 'Platform Support', 'Concepts', 2), siteDoc('architecture/skills-vs-tools-vs-extensions.md', 'architecture/skills-vs-tools-vs-extensions.md', 'Skills vs Tools vs Extensions', 'Architecture', 8.5), agentosDoc('OBSERVABILITY.md', 'architecture/observability.md', 'Observability (OpenTelemetry)', 'Architecture', 9), agentosDoc('LOGGING.md', 'architecture/logging.md', 'Logging (Pino + OpenTelemetry)', 'Architecture', 10), agentosDoc('CONTENT_SAFE_VOICE.md', 'architecture/content-safe-voice.md', 'Content-Safe Voice Diagnostics', 'Architecture', 10.5), agentosDoc('TOOL_CALLING_AND_LOADING.md', 'architecture/tool-calling-and-loading.md', 'Tool Calling & Lazy Loading', 'Tools & Capabilities', 11), agentosDoc('LLM_PROVIDERS.md', 'architecture/llm-providers.md', 'LLM Providers', 'Architecture', 12), agentosDoc('KEY_ROTATION.md', 'architecture/key-rotation.md', 'API Key Rotation', 'Architecture', 12.5), // The page documents the claude-code-cli and gemini-cli provider bridges, so it sits with the // provider pages. Its dest keeps the URL it was first published at, so links to it hold. agentosDoc('features/CLI_ERROR_CODES.md', 'extensions/built-in/cli-error-codes.md', 'CLI Error Codes', 'Architecture', 12.7), agentosDoc('STREAMING_SEMANTICS.md', 'architecture/streaming-semantics.md', 'Streaming Semantics', 'Architecture', 13), agentosDoc('OAUTH_AUTH.md', 'architecture/oauth-auth.md', 'OAuth Auth', 'Architecture', 14), agentosDoc('ORCHESTRATION.md', 'features/orchestration-guide.md', 'Orchestration Guide', 'Orchestration', 1, { sidebar: false, }), agentosDoc('UNIFIED_ORCHESTRATION.md', 'features/unified-orchestration.md', 'Unified Orchestration Layer', 'Orchestration', 2), agentosDoc('MISSION_API.md', 'features/mission-api.md', 'mission() API', 'Orchestration', 3), agentosDoc('WORKFLOW_DSL.md', 'features/workflow-dsl.md', 'workflow() DSL', 'Orchestration', 4), agentosDoc('AGENT_GRAPH.md', 'features/agent-graph.md', 'AgentGraph', 'Orchestration', 5), agentosDoc('CHECKPOINTING.md', 'features/checkpointing.md', 'Checkpointing and Time-Travel', 'Orchestration', 6), agentosDoc('PLANNING_ENGINE.md', 'features/planning-engine.md', 'Planning Engine', 'Orchestration', 7), agentosDoc('COGNITIVE_PIPELINE.md', 'features/cognitive-pipeline.md', 'Cognitive Pipeline (Smart Per-Message Orchestration)', 'Cognitive Pipeline', 9), // Overview (start here) agentosDoc('MEMORY_SYSTEM_OVERVIEW.md', 'features/memory-system-overview.md', 'Memory System Overview', 'Memory', 1), // Cognitive deep-dive agentosDoc('COGNITIVE_MEMORY.md', 'features/cognitive-memory.md', 'Cognitive Memory', 'Memory', 3), agentosDoc('PERSONAS.md', 'features/personas.md', 'Defining and Loading Personas', 'Personas', 1), agentosDoc('HEXACO_PERSONALITY.md', 'features/hexaco-personality.md', 'HEXACO Personality', 'Personas', 4), agentosDoc('SOUL_FILES.md', 'features/soul-files.md', 'Soul Files & the Markdown Memory Wiki', 'Personas', 5), agentosDoc('ADAPTIVE_PROMPT_INTELLIGENCE.md', 'features/adaptive-prompt-intelligence.md', 'Adaptive Prompt Intelligence', 'Personas', 5.5), agentosDoc('WORKING_MEMORY.md', 'features/working-memory.md', 'Working Memory', 'Memory', 6), // How to use it — consolidated page (auto-ingest + agent tools + import/export) agentosDoc('MEMORY_OPERATIONS.md', 'features/memory-operations.md', 'Memory Operations', 'Memory', 8), // Scale & storage (consolidated SQL adapter quickstart + 4-tier scaling path) agentosDoc('SQL_STORAGE_QUICKSTART.md', 'features/sql-storage.md', 'Storage & Scaling', 'Memory', 12), // Hidden backend reference pages (linked from Scaling, not in nav) agentosDoc('CLIENT_SIDE_STORAGE.md', 'features/client-side-storage.md', 'Client-Side Storage', 'Memory', 13, { sidebar: false, }), agentosDoc('MEMORY_STORAGE.md', 'features/memory-storage.md', 'SQLite Brain Storage', 'Memory', 14, { sidebar: false, }), agentosDoc('POSTGRES_BACKEND.md', 'features/postgres-backend.md', 'Postgres + pgvector Backend', 'Memory', 15, { sidebar: false, }), agentosDoc('QDRANT_BACKEND.md', 'features/qdrant-backend.md', 'Qdrant Backend', 'Memory', 16, { sidebar: false, }), agentosDoc('PINECONE_BACKEND.md', 'features/pinecone-backend.md', 'Pinecone Backend', 'Memory', 17, { sidebar: false, }), extraDoc('packages/sql-storage-adapter/PLATFORM_STRATEGY.md', 'features/platform-strategy.md', 'Platform Strategy', 'Memory', 18, { sidebar: false, }), agentosDoc('RAG_MEMORY_CONFIGURATION.md', 'features/rag-memory.md', 'RAG Memory Configuration', 'RAG & Retrieval', 1), agentosDoc('HYDE_RETRIEVAL.md', 'features/hyde-retrieval.md', 'HyDE Retrieval', 'RAG & Retrieval', 2), agentosDoc('architecture/hybrid-retriever.md', 'architecture/hybrid-retriever.md', 'Hybrid BM25 + Dense Retriever', 'RAG & Retrieval', 3), agentosDoc('architecture/session-retriever.md', 'architecture/session-retriever.md', 'Session-Level Hierarchical Retriever', 'RAG & Retrieval', 3.5), agentosDoc('QUERY_ROUTER.md', 'features/query-routing.md', 'Query Router (Stage 1: Memory-or-Not Gate)', 'Cognitive Pipeline', 4), agentosDoc('MEMORY_ROUTER.md', 'features/memory-router.md', 'Memory Router (Stage 2: Recall-Stage Smart Orchestration)', 'Cognitive Pipeline', 4.1), agentosDoc('INGEST_ROUTER.md', 'features/ingest-router.md', 'Ingest Router (Input-Stage Smart Orchestration)', 'Cognitive Pipeline', 4.2), agentosDoc('READ_ROUTER.md', 'features/read-router.md', 'Read Router (Stage 3: Reader Strategy + Model Dispatch)', 'Cognitive Pipeline', 4.3), agentosDoc('ADAPTIVE_MEMORY_ROUTER.md', 'features/adaptive-memory-router.md', 'Adaptive Memory Router (Self-Calibrating)', 'Cognitive Pipeline', 4.4), siteDoc('features/citation-verification.md', 'features/citation-verification.md', 'Citation Verification', 'RAG & Retrieval', 4.5), agentosDoc('MULTIMODAL_RAG.md', 'features/multimodal-rag.md', 'Multimodal RAG (Image + Audio)', 'RAG & Retrieval', 5), agentosDoc('MEMORY_DOCUMENT_INGESTION.md', 'features/memory-document-ingestion.md', 'Document Ingestion', 'RAG & Retrieval', 6), agentosDoc('INCREMENTAL_VECTOR_INGESTION.md', 'features/incremental-vector-ingestion.md', 'Incremental Vector Ingestion', 'RAG & Retrieval', 7), agentosDoc('features/LIBRARY_INDEX.md', 'features/library-index.md', 'Library Index', 'RAG & Retrieval', 7.5), // Text processing, statistics and search agentosDoc('text/TEXT_OVERVIEW.md', 'text/index.md', 'Text Processing & Search', 'Text Processing & Search', 1, { categoryIndex: true, }), agentosDoc('text/TEXT_PROCESSING.md', 'text/text-processing.md', 'Text Processing Pipeline', 'Text Processing & Search', 2), agentosDoc('text/TEXT_STATISTICS.md', 'text/text-statistics.md', 'Text Statistics and Classification', 'Text Processing & Search', 3), agentosDoc('text/LEXICAL_AND_HYBRID_SEARCH.md', 'text/lexical-and-hybrid-search.md', 'Lexical and Hybrid Search', 'Text Processing & Search', 4), agentosDoc('text/CHUNKING_AND_SNIPPETS.md', 'text/chunking-and-snippets.md', 'Chunking and Snippets', 'Text Processing & Search', 5), agentosDoc('text/RERANKING.md', 'text/reranking.md', 'Reranking', 'Text Processing & Search', 6), agentosDoc('GUARDRAILS_USAGE.md', 'features/guardrails.md', 'Guardrails', 'Guardrails & Safety', 1), staticDoc('features/guardrails-architecture.md', 'features/guardrails-architecture.md', 'Guardrails Architecture', 'Guardrails & Safety', 1.5), agentosDoc('HUMAN_IN_THE_LOOP.md', 'features/human-in-the-loop.md', 'Human-in-the-Loop (HITL)', 'Guardrails & Safety', 1.8), agentosDoc('PII_REDACTION.md', 'features/pii-redaction.md', 'PII Redaction (and PHI scrubbing)', 'Guardrails & Safety', 1.9), agentosDoc('CREATING_GUARDRAILS.md', 'features/creating-guardrails.md', 'Creating Custom Guardrails', 'Guardrails & Safety', 2), agentosDoc('SAFETY_PRIMITIVES.md', 'features/safety-primitives.md', 'Safety Primitives', 'Guardrails & Safety', 3), agentosDoc('features/VOICE_PLATFORM.md', 'features/voice-platform.md', 'Voice Platform Runtime', 'Voice & Speech', 0.5), agentosDoc('VOICE_PIPELINE.md', 'features/voice-pipeline.md', 'Voice Pipeline', 'Voice & Speech', 1), agentosDoc('SPEECH_PROVIDERS.md', 'features/speech-providers.md', 'Speech Providers', 'Voice & Speech', 2), agentosDoc('MEETING_BOTS.md', 'features/meeting-bots.md', 'Meeting Bots', 'Voice & Speech', 4), agentosDoc('TELEPHONY_PROVIDERS.md', 'features/telephony-providers.md', 'Telephony Providers', 'Voice & Speech', 3), agentosDoc('features/REALTIME_AVATARS.md', 'features/realtime-avatars.md', 'Realtime Avatars', 'Voice & Speech', 5), agentosDoc('IMAGE_GENERATION.md', 'features/image-generation.md', 'Image Generation', 'Media Generation', 1), agentosDoc('IMAGE_EDITING.md', 'features/image-editing.md', 'Image Editing (Img2Img, Inpainting, Upscaling)', 'Media Generation', 2), agentosDoc('CHARACTER_CONSISTENCY.md', 'features/character-consistency.md', 'Character Consistency', 'Media Generation', 2.5), agentosDoc('STYLE_TRANSFER.md', 'features/style-transfer.md', 'Style Transfer', 'Media Generation', 2.6), agentosDoc('VISION_PIPELINE.md', 'features/vision-pipeline.md', 'Vision Pipeline (OCR & Image Understanding)', 'Media Generation', 3), agentosDoc('IMAGE_SEGMENTATION.md', 'features/image-segmentation.md', 'Image Segmentation and Background Removal', 'Media Generation', 3.5), staticDoc('features/audio-generation.md', 'features/audio-generation.md', 'Audio Generation', 'Media Generation', 4), staticDoc('features/provider-preferences.md', 'features/provider-preferences.md', 'Provider Preferences', 'Media Generation', 5), staticDoc('features/video-pipeline.md', 'features/video-pipeline.md', 'Video Pipeline', 'Media Generation', 6), agentosDoc('CHANNELS.md', 'features/channels.md', 'Channels', 'Channels & Social', 1), agentosDoc('SOCIAL_POSTING.md', 'features/social-posting.md', 'Social Posting', 'Channels & Social', 2), agentosDoc('STRUCTURED_OUTPUT.md', 'features/structured-output.md', 'Structured Output', 'Tools & Capabilities', 1), siteDoc('features/llm-output-validation.md', 'features/llm-output-validation.md', 'LLM Output Validation', 'Model Quality & Cost', 1.5), agentosDoc('EVALUATION.md', 'features/evaluation-guide.md', 'Evaluation Guide', 'Model Quality & Cost', 2), agentosDoc('features/PROMPT_CACHING.md', 'features/prompt-caching.md', 'Prompt Caching', 'Model Quality & Cost', 2.5), agentosDoc('features/CACHE_DIAGNOSTICS.md', 'features/cache-diagnostics.md', 'Cache Diagnostics', 'Model Quality & Cost', 2.6), agentosDoc('COST_OPTIMIZATION.md', 'features/cost-optimization.md', 'Cost Optimization', 'Model Quality & Cost', 3), agentosDoc('UNCENSORED_CONTENT.md', 'features/uncensored-content.md', 'Uncensored Content & Policy-Tier Routing', 'Model Quality & Cost', 3.5), agentosDoc('EVALUATION_FRAMEWORK.md', 'features/evaluation-framework.md', 'Evaluation Framework', 'Model Quality & Cost', 4, { sidebar: false, }), agentosDoc('STRUCTURED_OUTPUT_API.md', 'features/structured-output-api.md', 'Structured Output API (generateObject / streamObject / embedText)', 'Tools & Capabilities', 5, { sidebar: false, }), agentosDoc('features/STRUCTURED_REPLY.md', 'features/structured-reply.md', 'Structured Reply', 'Tools & Capabilities', 5.5), agentosDoc('CAPABILITY_DISCOVERY.md', 'features/capability-discovery.md', 'Capability Discovery', 'Tools & Capabilities', 1), agentosDoc('EMERGENT_CAPABILITIES.md', 'features/emergent-capabilities.md', 'Emergent Capabilities', 'Tools & Capabilities', 2), agentosDoc('PARACOSM.md', 'features/paracosm.md', 'Paracosm — Agent Swarm Simulation for Structured World Modeling with LLMs', 'Paracosm', 1), extensionDoc('AGENCY_COLLABORATION_EXAMPLE.md', 'features/agency-collaboration.md', 'Agency Collaboration', 3, { section: 'Orchestration', }), agentosDoc('AGENT_COMMUNICATION.md', 'features/agent-communication.md', 'Agent Communication', 'Orchestration', 4), agentosDoc('MEMORY_CONSOLIDATION.md', 'features/memory-consolidation.md', 'Memory Consolidation', 'Memory', 6, { sidebar: false, }), staticDoc('features/self-improving-agents.md', 'features/self-improving-agents.md', 'Self-Improving Agents', 'Tools & Capabilities', 6.5), agentosDoc('PROVENANCE_IMMUTABILITY.md', 'features/provenance-immutability.md', 'Provenance & Immutability', 'Provenance', 7), agentosDoc('IMMUTABLE_AGENTS.md', 'features/immutable-agents.md', 'Immutable Agents', 'Provenance', 8), agentosDoc('AGENT_CONFIG_EXPORT.md', 'features/agent-config-export.md', 'Agent Config Export & Import', 'Tools & Capabilities', 9), agentosDoc('DISCOVERY.md', 'features/discovery-guide.md', 'Capability Discovery Guide', 'Tools & Capabilities', 10, { sidebar: false, }), agentosDoc('PROVENANCE.md', 'features/provenance-guide.md', 'Provenance Guide', 'Provenance', 11, { sidebar: false, }), agentosDoc('AGENCY_API.md', 'features/agency-api.md', 'Multi-Agent Agency API', 'Orchestration', 12, { sidebar: false, }), agentosDoc('CLI_PROVIDERS.md', 'features/cli-providers.md', 'CLI Providers', 'Model Quality & Cost', 13, { sidebar: false, }), staticDoc('features/github-integration.md', 'features/github-integration.md', 'GitHub Integration', 'Channels & Social', 13.5), staticDoc('features/document-export.md', 'features/document-export.md', 'Document Export', 'Extensions', 13.6), entry({ sourceType: 'canonical-guide', sourcePath: 'packages/agentos/docs/SKILLS_OVERVIEW.md', dest: 'skills/index.md', title: 'Skills Overview', section: 'Skills', position: 1, categoryIndex: true, }), entry({ sourceType: 'canonical-guide', sourcePath: 'packages/agentos/docs/extensions/SKILLS.md', dest: 'skills/skill-format.md', title: 'Skills (SKILL.md)', section: 'Skills', position: 2, }), entry({ sourceType: 'package-readme', sourcePath: 'packages/agentos-skills/README.md', dest: 'skills/agentos-skills.md', title: '@framers/agentos-skills', section: 'Skills', position: 3, }), entry({ sourceType: 'package-readme', sourcePath: 'packages/agentos-skills-registry/README.md', dest: 'skills/agentos-skills-registry.md', title: '@framers/agentos-skills-registry', section: 'Skills', position: 4, }), extensionDoc('README.md', 'extensions/index.md', 'Extensions Overview', 1, { categoryIndex: true, }), extensionDoc('HOW_EXTENSIONS_WORK.md', 'extensions/how-extensions-work.md', 'How Extensions Work', 2), extensionDoc('EXTENSION_ARCHITECTURE.md', 'extensions/extension-architecture.md', 'Extension Architecture', 3), extensionDoc('AUTO_LOADING_EXTENSIONS.md', 'extensions/auto-loading.md', 'Auto-Loading Extensions', 4), agentosDoc('RFC_EXTENSION_STANDARDS.md', 'extensions/extension-standards.md', 'Extension Standards (RFC)', 'Extensions', 5), extensionDoc('CONTRIBUTING.md', 'extensions/contributing.md', 'Contributing', 6), extensionDoc('SELF_HOSTED_REGISTRIES.md', 'extensions/self-hosted-registries.md', 'Self-Hosted Registries', 7), extensionDoc('MIGRATION_GUIDE.md', 'extensions/migration-guide.md', 'Migration Guide', 8), extensionDoc('RELEASING.md', 'extensions/releasing.md', 'Releasing', 9), builtInExtension('research/web-search', 'extensions/built-in/web-search.md', 'Web Search', 1), builtInExtension('research/web-browser', 'extensions/built-in/web-browser.md', 'Web Browser', 2), builtInExtension('research/news-search', 'extensions/built-in/news-search.md', 'News Search', 3), builtInExtension('system/cli-executor', 'extensions/built-in/cli-executor.md', 'CLI Executor', 4), agentosDoc('features/CLI_REGISTRY.md', 'extensions/built-in/cli-registry.md', 'CLI Registry', 'Extensions', 5, { group: 'Official Extensions', }), builtInExtension('auth', 'extensions/built-in/auth.md', 'Auth', 6), builtInExtension('media/giphy', 'extensions/built-in/giphy.md', 'Giphy', 7), builtInExtension('media/image-search', 'extensions/built-in/image-search.md', 'Image Search', 8), builtInExtension('media/voice-synthesis', 'extensions/built-in/voice-synthesis.md', 'Voice Synthesis', 9), builtInExtension('integrations/telegram', 'extensions/built-in/telegram.md', 'Telegram', 10), builtInExtension('communications/telegram-bot', 'extensions/built-in/telegram-bot.md', 'Telegram Bot (Comms)', 11), builtInExtension('channels/discord', 'extensions/built-in/channel-discord.md', 'Channel: Discord', 12), builtInExtension('channels/slack', 'extensions/built-in/channel-slack.md', 'Channel: Slack', 13), builtInExtension('channels/telegram', 'extensions/built-in/channel-telegram.md', 'Channel: Telegram', 14), builtInExtension('channels/whatsapp', 'extensions/built-in/channel-whatsapp.md', 'Channel: WhatsApp', 15), builtInExtension('channels/webchat', 'extensions/built-in/channel-webchat.md', 'Channel: WebChat', 16), builtInExtension('research/citation-verifier', 'extensions/built-in/citation-verifier.md', 'Citation Verifier', 16.1), builtInExtension('tools/local-file-search', 'extensions/built-in/local-file-search.md', 'Local File Search', 16.2), builtInExtension('tools/send-file-to-channel', 'extensions/built-in/send-file-to-channel.md', 'Send File to Channel', 16.3), builtInExtension('research/trulia-search', 'extensions/built-in/trulia-search.md', 'Trulia Search', 16.4), builtInExtension('tools/zip-files', 'extensions/built-in/zip-files.md', 'Zip Files', 16.5), staticDoc('extensions/built-in/pii-redaction.md', 'extensions/built-in/pii-redaction.md', 'PII Redaction', 'Extensions', 17, { group: 'Guardrail Extensions', }), staticDoc('extensions/built-in/ml-classifiers.md', 'extensions/built-in/ml-classifiers.md', 'ML Content Classifiers', 'Extensions', 17.1, { group: 'Guardrail Extensions', }), staticDoc('extensions/built-in/topicality.md', 'extensions/built-in/topicality.md', 'Topicality', 'Extensions', 17.2, { group: 'Guardrail Extensions', }), staticDoc('extensions/built-in/code-safety.md', 'extensions/built-in/code-safety.md', 'Code Safety', 'Extensions', 17.3, { group: 'Guardrail Extensions', }), staticDoc('extensions/built-in/grounding-guard.md', 'extensions/built-in/grounding-guard.md', 'Grounding Guard', 'Extensions', 17.4, { group: 'Guardrail Extensions', }), builtInExtension('safety/content-policy-rewriter', 'extensions/built-in/content-policy-rewriter.md', 'Content Policy Rewriter', 17.5, { group: 'Guardrail Extensions', }), builtInExtension('provenance/anchor-providers', 'extensions/built-in/anchor-providers.md', 'Anchor Providers', 18, { group: 'Provenance Extensions', }), extraDoc('packages/agentos/CHANGELOG.md', 'getting-started/changelog.md', 'Changelog', 'Getting Started', 7), siteDoc('wunderland/index.md', 'wunderland/index.md', 'Wunderland — Getting Started', 'Wunderland', 1, { categoryIndex: true, }), agentosDoc('contributing/new-provider.md', 'contributing/new-provider.md', 'Adding an LLM Provider', 'Contributing', 1), ]; function resolvePublicationSourcePath(monoRoot, entryConfig) { const sourcePath = entryConfig.sourcePath; if (!sourcePath) return null; const absolutePath = resolve(monoRoot, sourcePath); if (existsSync(absolutePath)) return absolutePath; const fileName = basename(absolutePath); const searchRoot = dirname(absolutePath); if (existsSync(searchRoot)) { for (const subdir of DOC_SEARCH_SUBDIRS) { const candidate = resolve(searchRoot, subdir, fileName); if (existsSync(candidate)) return candidate; } } const vendoredPath = resolve( monoRoot, 'apps/agentos-live-docs/vendored-docs', sourcePath, ); if (existsSync(vendoredPath)) return vendoredPath; return null; } function buildPublicationInventory(monoRoot) { const seen = new Map(); const duplicates = []; const missingSources = []; const stubbedDestinations = []; for (const manifestEntry of publicationManifest) { if (seen.has(manifestEntry.dest) && !duplicates.includes(manifestEntry.dest)) { duplicates.push(manifestEntry.dest); } seen.set(manifestEntry.dest, manifestEntry); const resolvedSource = resolvePublicationSourcePath(monoRoot, manifestEntry); if (resolvedSource) continue; if (manifestEntry.allowMissingSource || manifestEntry.sourceType === 'generated-stub') { stubbedDestinations.push(manifestEntry.dest); continue; } missingSources.push(manifestEntry.sourcePath); } return { duplicates: duplicates.sort(), missingSources: missingSources.sort(), generatedDestinations: publicationManifest.map((item) => item.dest).sort(), stubbedDestinations: stubbedDestinations.sort(), }; } function docIdFromDest(dest) { return dest.replace(/\.md$/, ''); } function publicRouteFromDest(dest) { return `/${docIdFromDest(dest).replace(/\/index$/, '')}`; } /** * Maps each source file name to the route of the first entry that publishes a * file of that name. The docs site matches a link's file name case-insensitively * and reads '-' as '_' (`normalizeDocKey` in agentos-live-docs * `scripts/pull-docs-links.mjs`), and there a later name with the same key * replaces an earlier one. So the first entry keeps the key: links written to * `PII_REDACTION.md` reach the guide at /features/pii-redaction, not the * extension page published from `pii-redaction.md`. */ function buildFilenameRewriteMap() { const rewrites = {}; const takenKeys = new Set(); for (const manifestEntry of publicationManifest) { if (!manifestEntry.sourcePath?.endsWith('.md')) continue; const fileName = basename(manifestEntry.sourcePath); const key = fileName.toLowerCase().replace(/-/g, '_'); if (takenKeys.has(key)) continue; takenKeys.add(key); rewrites[fileName] = publicRouteFromDest(manifestEntry.dest); } return rewrites; } function buildGuideSidebar() { const sectionEntries = new Map(); for (const manifestEntry of publicationManifest) { if (manifestEntry.sidebar === false) continue; if (!sectionEntries.has(manifestEntry.section)) { sectionEntries.set(manifestEntry.section, []); } sectionEntries.get(manifestEntry.section).push(manifestEntry); } return SECTION_ORDER .filter((section) => sectionEntries.has(section)) .map((section) => { const entries = sectionEntries .get(section) .slice() .sort((left, right) => left.position - right.position); const categoryIndex = entries.find((item) => item.categoryIndex); const directItems = entries .filter((item) => !item.categoryIndex && !item.group) .map((item) => docIdFromDest(item.dest)); const groupedItems = Array.from( entries .filter((item) => item.group) .reduce((groups, item) => { if (!groups.has(item.group)) groups.set(item.group, []); groups.get(item.group).push(item); return groups; }, new Map()), ).map(([group, items]) => ({ type: 'category', label: group, collapsed: false, items: items .slice() .sort((left, right) => left.position - right.position) .map((item) => docIdFromDest(item.dest)), })); const category = { type: 'category', label: section, collapsed: section === 'Getting Started' ? false : undefined, items: directItems.concat(groupedItems), }; if (categoryIndex) { category.link = { type: 'doc', id: docIdFromDest(categoryIndex.dest) }; } else { // Fall back to a generated section index so the breadcrumb for // pages inside this category is a clickable landing page rather // than inert text. category.link = { type: 'generated-index', slug: `/category/${section .toLowerCase() .replace(/&/g, 'and') .replace(/[^a-z0-9]+/g, '-') .replace(/(^-|-$)/g, '')}`, title: section, description: `All ${section} pages in the AgentOS documentation.`, }; } return category; }); } module.exports = { publicationManifest, buildPublicationInventory, buildGuideSidebar, buildFilenameRewriteMap, resolvePublicationSourcePath, };