Illuminating Project Docs: How We Built a Dynamic, Interactive Documentation Hub
We've rolled out a powerful new 'Docs' tab on our project pages, transforming raw markdown into interactive, intelligent documentation with Mermaid diagrams, mathematical notation, and seamless GitHub integration, all while learning some valuable lessons along the way.
Documentation: it's the lifeblood of any complex project, yet often the first thing to fall by the wayside or get scattered across disparate systems. We've all been there – hunting through wikis, outdated READMEs, and fragmented notes trying to piece together how a system works.
Our goal was simple but ambitious: create a unified, dynamic, and intelligent documentation experience directly within our project detail pages. We wanted to move beyond static links and bring our project's docs/ folder on GitHub to life, complete with advanced rendering capabilities and automated content generation. This post dives into the journey of building our new "Docs" tab, the technical decisions we made, and the unexpected challenges we overcame.
The Vision: A Unified Documentation Experience
Imagine navigating to a project in our application and instantly having access to its comprehensive documentation, pulled directly from its linked GitHub repository. Not just plain text, but beautifully rendered markdown, interactive diagrams, and complex mathematical equations. This was the vision for our new "Docs" tab.
Specifically, we aimed for:
- Dynamic Content: Fetching
*.mdfiles from a project's/docs/folder on GitHub. - Rich Markdown Support: Beyond basic markdown, we needed Mermaid for diagrams and Katex for mathematical notation.
- Intelligent Linking: Automatically transforming internal file paths (like
src/server/somefile.ts) into clickable GitHub blob URLs. - Structured Organization: Moving our existing, often lengthy, intelligence documentation into modular, individual files within the
docs/folder. - Automated Generation: Leveraging our background agents to generate and update these new documentation sections.
Under the Hood: Crafting the Docs Tab
Bringing this vision to life required a multi-faceted approach, touching both our backend API and frontend components.
Backend Brilliance with tRPC
At the heart of our data fetching lies our src/server/trpc/routers/projects.ts router. We extended it with a new docs sub-router.
docs.list: This procedure usesfetchRepoTreeto scan the linked GitHub repository's/docs/folder, returning a list of available markdown files.docs.get: Given a file path, this procedure leveragesfetchFileContentto retrieve the raw markdown content, performing initial parsing to extract the title and a brief summary.
This setup ensures that our documentation is always up-to-date with the latest version on GitHub, without needing to sync or store it redundantly.
Frontend Flair: The DocsTab Component
The user interface for our documentation lives in src/app/(dashboard)/dashboard/projects/[id]/page.tsx. We introduced a new DocsTab component, intelligently managing three states:
- Docs List Grid: A visual grid displaying all available documentation sections, fetched via
docs.list. - Summary Card: A concise overview (title + summary) of a selected document.
- Full Rendered Doc: The main event – the complete, beautifully rendered markdown content of a chosen document.
This progressive disclosure approach keeps the UI clean and helps users navigate through potentially vast amounts of documentation. We also added the necessary <TabsTrigger value="docs"> and <TabsContent value="docs"> to integrate seamlessly with our existing tabbed interface.
Markdown Reimagined: Mermaid, Math, and GitHub Links
The real magic happens in src/components/markdown-renderer.tsx. We transformed a standard markdown renderer into a powerful visualization engine:
- Mathematical Notation: By integrating
remark-mathandrehype-katex(along with thekatexlibrary), we enabled full support for LaTeX-style inline ($inline$) and block ($$block$$) mathematical expressions. This is crucial for documenting algorithms and complex technical concepts. - Interactive Diagrams: We added a
MermaidDiagramcomponent, which dynamically imports themermaidlibrary and renders Mermaid code blocks as scalable SVG diagrams. Crucially, it respects our application's dark theme, ensuring a consistent visual experience. - Intelligent
RepoLinkComponent: One of the most powerful additions is theRepoLinkcomponent. When provided withgithubOwnerandgithubRepoprops, it intelligently converts internal file-path links (e.g.,src/server/trpc/routers/projects.ts) within the markdown into direct links to the corresponding files on GitHub's blob viewer. This bridges the gap between documentation and source code, making navigation incredibly intuitive.
Naturally, these enhancements required updating our package.json and package-lock.json to include mermaid, remark-math, rehype-katex, and katex.
Structuring Knowledge: The docs/ Revolution
Beyond rendering, we also tackled the organization of our project intelligence documentation. What were once large, monolithic files (e.g., /tmp/nyxcore-doc-part{1,2,3}.md) have now been systematically split into individual, focused files within the project's new /docs/ folder (e.g., 01-executive-summary.md through 11-real-world-examples.md).
This modular approach not only improves readability but also facilitates targeted updates. Furthermore, we're leveraging our background agents to automatically generate and commit new documentation sections, such as 12-auto-fix.md, 13-refactor.md, and others, ensuring our documentation evolves alongside the codebase.
Navigating the Rapids: Lessons Learned & Solutions
No development session is without its bumps. Here are a few critical challenges we encountered and how we navigated them:
-
The npm Cache Conundrum (
EACCES):- Challenge: We ran into persistent
EACCESerrors due to root-owned files in the default~/.npm/_cacache/directory, preventingnpm installfrom completing reliably. Attempts tonpm cache clean --forcewere futile. - Solution: The most reliable workaround was to explicitly direct npm to use a temporary cache directory:
npm install --cache /tmp/npm-cache-nyxcore. This allowed development to proceed without permission headaches, and the temporary cache can be safely deleted afterward.
- Challenge: We ran into persistent
-
TypeScript's Strict Regex (
/sflag):- Challenge: While attempting to use the
/s(dotAll) regex flag in TypeScript (/^(.+?)(?:\n\n|\n#|$)/s) for more flexible multi-line matching, we hit aTS1501error: "This regular expression flag is only available when targeting 'es2018' or later." Our current TS target was older. - Solution: We adapted the regex to use
[\s\S]instead of.to match any character (including newlines), achieving the same effect:/^([\s\S]+?)(?:\n\n|\n#|$)/. A simple but effective fix.
- Challenge: While attempting to use the
-
Taming Large Language Models: Prompt Length Limits:
- Challenge: Our initial strategy for generating documentation involved a single background agent attempting to read and process many large source files simultaneously. This quickly led to "Prompt is too long" errors, as the combined input exceeded the LLM's context window.
- Solution: We re-architected the document generation process. Instead of one monolithic task, we split it into multiple parallel agents, each with a narrower scope (e.g., one agent for sections 12-16, another for 17-20). We even used a separate Bash agent to handle the initial file-splitting, ensuring each LLM agent received manageable chunks of information. This allowed us to successfully generate complex documentation without hitting API limits.
What's Next on Our Journey
While the core functionality is committed and pushed (1894359), a few pieces are still in motion:
- Our background agents are actively working on generating
docs/14-code-analysis.md,docs/15-action-points.md,docs/16-discussion-service.md, anddocs/20-sidebar-active-processes.md. Once complete, these will be committed and pushed. - The next immediate steps involve verifying the end-to-end functionality of the Docs tab on a project with a linked GitHub repo, ensuring Mermaid diagrams render correctly in dark mode, and checking math equations.
- We're also considering adding a
docs/00-index.mdREADME file to provide a curated overview and links to all available sections.
Conclusion
Building the "Docs" tab has been a rewarding journey, significantly enhancing our developer experience by centralizing and enriching project documentation. By integrating dynamic content fetching from GitHub, powerful markdown rendering with Mermaid and Katex, and intelligent linking, we've transformed how we interact with our project knowledge. The lessons learned along the way, from npm cache woes to LLM prompt management, have only strengthened our development practices.
We're excited about the future of intelligent, integrated documentation and the continued impact it will have on our team's productivity and understanding of our complex systems.