From 681099e3a059628ecbbaa31b04d690e3dddd807a Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Mon, 2 Mar 2026 09:42:36 +0100 Subject: [PATCH 1/4] Enrich LLM-facing documentation with context, TOC, and cross-references Add rich SYSTEM headers to llms-full.txt and llms-small.txt with product context, supported platforms, and key capabilities. Insert a table of contents for navigation. Add related-page cross-references to help LLMs understand documentation relationships. Create llms-ctx.txt with concise product context. Reference llms-ctx.txt from llms.txt entry point. --- docs/public/llms-ctx.txt | 43 +++ .../src/integrations/llms-txt-post-process.ts | 255 +++++++++++++++++- 2 files changed, 292 insertions(+), 6 deletions(-) create mode 100644 docs/public/llms-ctx.txt diff --git a/docs/public/llms-ctx.txt b/docs/public/llms-ctx.txt new file mode 100644 index 00000000..e541b74b --- /dev/null +++ b/docs/public/llms-ctx.txt @@ -0,0 +1,43 @@ +# RocketSim — Product Context + +## What is RocketSim? +RocketSim is a macOS developer tool that enhances Apple's iOS Simulator with professional-grade features for capturing, debugging, testing, and design validation. It's available on the Mac App Store and used by individual developers and large teams worldwide. + +## Who is it for? +iOS, macOS, watchOS, and visionOS developers who use Xcode and the iOS Simulator for app development and testing. + +## Core Feature Areas + +### Capturing +Professional screenshots and recordings with device bezels, custom backgrounds, touch indicators, and App Store Connect optimization. Supports GIF, MP4, and JPEG/PNG formats. + +### Networking +Real-time network traffic monitoring via RocketSim Connect, historical networking insights, and network speed throttling (3G, Edge, airplane mode) for testing poor connectivity. + +### App Actions +Test push notifications, deep links/universal links, location simulation, and privacy permissions without a physical device. Manage everything from a persistent side window. + +### Design Comparison +Overlay design mockups from Figma or Sketch with adjustable opacity. Add grid overlays and rulers. Use the pixel-level magnifier for precise layout verification. + +### Accessibility +Toggle accessibility settings (Dynamic Type, Increase Contrast, Bold Text, Reduce Motion, etc.) from the side window. VoiceOver Navigator visualizes element order and supports keyboard-driven navigation. + +### Build Insights +Track Xcode build counts, durations, and trends. Compare incremental vs. clean builds. Team Build Insights lets teams compare performance across machines and Xcode versions. + +### Other +User Defaults real-time editor, status bar customization, simulator camera support, and configurable keyboard shortcuts. + +## Technical Details +- Platform: macOS (enhances the iOS/watchOS/visionOS Simulator in Xcode) +- Distribution: Mac App Store + direct enterprise distribution +- Sandboxed: Yes +- RocketSim Connect: Local Bonjour-based framework for Simulator-to-RocketSim communication (debug builds only) + +## Links +- Website: https://www.rocketsim.app +- Documentation: https://www.rocketsim.app/docs +- GitHub (issues & features): https://github.com/AvdLee/RocketSimApp +- YouTube: https://www.youtube.com/@rocketsimapp +- Developer: Antoine van der Lee (https://www.avanderlee.com) diff --git a/docs/src/integrations/llms-txt-post-process.ts b/docs/src/integrations/llms-txt-post-process.ts index f87ad291..e51abae4 100644 --- a/docs/src/integrations/llms-txt-post-process.ts +++ b/docs/src/integrations/llms-txt-post-process.ts @@ -3,8 +3,170 @@ import { readFile, writeFile } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import path from "node:path"; +const FULL_SYSTEM_HEADER = ` +This is the official documentation for RocketSim, a macOS developer tool that enhances Apple's iOS Simulator. + +Product: RocketSim — available on the Mac App Store +Developer: Antoine van der Lee (https://www.avanderlee.com) +Website: https://www.rocketsim.app +Supported platforms: iOS, macOS, watchOS, and visionOS development via the Simulator + +Key capabilities: +- Professional screenshot and video capture with device bezels and App Store Connect optimization +- Network traffic monitoring and debugging via RocketSim Connect +- Push notification testing without a physical device +- Deep link and universal link testing +- Location simulation with custom coordinates and predefined routes +- Design comparison with pixel-perfect overlays, grids, and rulers +- Accessibility testing: Dynamic Type, environment overrides, and VoiceOver Navigator +- Xcode build insights and team build analytics +- User Defaults real-time editor +- Network speed throttling and Simulator airplane mode +- Privacy permission management (grant, revoke, reset) + +Target audience: iOS, macOS, watchOS, and visionOS developers using Xcode and the Simulator. +`; + +const SMALL_SYSTEM_HEADER = ` +This is a compact version of the official documentation for RocketSim, a macOS developer tool that enhances Apple's iOS Simulator with features for capturing, networking, design comparison, accessibility testing, and more. + +Product: RocketSim — available on the Mac App Store +Developer: Antoine van der Lee (https://www.avanderlee.com) +Website: https://www.rocketsim.app +Supported platforms: iOS, macOS, watchOS, and visionOS development via the Simulator +Target audience: iOS, macOS, watchOS, and visionOS developers using Xcode and the Simulator. +`; + +const TABLE_OF_CONTENTS = `## Table of Contents + +### Getting Started +- Onboarding +- Product Tour & Quick Demos +- Configuring App Actions +- Setting Up RocketSim Connect +- How Large Teams Use RocketSim +- Additional Resources +- Testimonials + +### Screenshots & Recordings +- Taking Screenshots +- Creating Recordings +- Floating Thumbnail +- App Store Connect Optimization +- Touch Indicators +- 120 FPS Recordings + +### Simulator Camera +- Simulator Camera Support + +### Status Bar +- Status Bar Appearance + +### Design Comparison +- Comparing Designs +- Grids & Rulers +- Magnifier +- Slow Animations + +### App Actions +- App Directory Access +- Deep Links & Universal Links +- Location Simulation +- Privacy & Permissions +- Push Notifications +- Quick Actions + +### Networking +- Network Speed Control & Simulator Airplane Mode +- Network Traffic Monitoring +- Networking Insights + +### Build Insights +- Build Insights +- Team Build Insights + +### Accessibility +- Environment Overrides +- Toggles & Dynamic Text +- VoiceOver Navigator + +### Other Features +- User Defaults Editor + +### Settings +- Shortcuts +- Side Window + +### Support +- FAQ +- Reporting An Issue +- Requesting A Feature`; + +const RELATED_LINKS: Record = { + "Taking Screenshots": [ + "[Creating Recordings](/docs/features/capturing/recordings)", + "[App Store Connect Optimization](/docs/features/capturing/app-store-connect-optimization)", + "[Floating Thumbnail](/docs/features/capturing/floating-thumbnail)", + ], + "Creating Recordings": [ + "[Taking Screenshots](/docs/features/capturing/screenshots)", + "[Touch Indicators](/docs/features/capturing/touch-indicators)", + "[120 FPS Recordings](/docs/features/capturing/120-fps-recordings)", + ], + "Network Traffic Monitoring": [ + "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", + "[Networking Insights](/docs/features/networking/networking-insights)", + "[Network Speed Control](/docs/features/networking/network-speed-control)", + ], + "Networking Insights": [ + "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", + "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", + ], + "Network Speed Control & Simulator Airplane Mode": [ + "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", + "[Networking Insights](/docs/features/networking/networking-insights)", + ], + "Push Notifications": [ + "[Configuring App Actions](/docs/getting-started/configuring-app-actions)", + "[Deep Links & Universal Links](/docs/features/app-actions/deeplinks-universal-links)", + ], + "Deeplinks (Universal Links)": [ + "[Configuring App Actions](/docs/getting-started/configuring-app-actions)", + "[Push Notifications](/docs/features/app-actions/push-notifications)", + ], + "Build Insights": [ + "[Team Build Insights](/docs/features/build-insights/team-build-insights)", + ], + "Team Build Insights": [ + "[Build Insights](/docs/features/build-insights/build-insights)", + "[How Large Teams Use RocketSim](/docs/getting-started/how-large-teams-use-rocketsim)", + ], + "Comparing Designs": [ + "[Grids & Rulers](/docs/features/design-comparison/grids-and-rulers)", + "[Magnifier](/docs/features/design-comparison/magnifier)", + ], + "Environment Overrides": [ + "[Toggles & Dynamic Text](/docs/features/accessibility/toggles-and-dynamic-text)", + "[VoiceOver Navigator](/docs/features/accessibility/voiceover-navigator)", + ], + "VoiceOver Navigator": [ + "[Environment Overrides](/docs/features/accessibility/environment-overrides)", + "[Toggles & Dynamic Text](/docs/features/accessibility/toggles-and-dynamic-text)", + ], + "Simulator Camera Support": [ + "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", + ], + "Setting Up RocketSim Connect": [ + "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", + "[Simulator Camera Support](/docs/features/capturing/simulator-camera-support)", + ], +}; + /** * Post-processes the generated llms-full.txt and llms-small.txt files to: + * - Replace the SYSTEM header with an enriched product context block + * - Inject a table of contents for navigation + * - Add cross-reference "Related" links between related pages * - Remove the home/index page (only contains navigation components) * - Remove the 404 page * - Convert components to YouTube links @@ -14,6 +176,8 @@ import path from "node:path"; * - Convert :::tip/:::note directives to blockquotes (full) or strip them (small) * - Fix escaped bold-in-link markdown as safety net * - Differentiate llms-small.txt (strip testimonials, tips, extra whitespace) + * + * Also enhances llms.txt with a reference to llms-ctx.txt. */ export function llmsTxtPostProcess(): AstroIntegration { return { @@ -37,16 +201,84 @@ export function llmsTxtPostProcess(): AstroIntegration { // File might not exist, skip } } + + await enhanceLlmsTxtIndex(outputDir); }, }, }; } +async function enhanceLlmsTxtIndex(outputDir: string): Promise { + const llmsTxtPath = path.join(outputDir, "llms.txt"); + try { + const buildDate = new Date().toISOString().split("T")[0]; + const enhancedLlmsTxt = `# RocketSim + +> RocketSim is a macOS developer tool that enhances Apple's iOS Simulator with professional-grade features for capturing, debugging, testing, and design validation. Available on the Mac App Store for iOS, macOS, watchOS, and visionOS developers. + +Last updated: ${buildDate} +Website: https://www.rocketsim.app +Documentation: https://www.rocketsim.app/docs +GitHub: https://github.com/AvdLee/RocketSimApp +Support: support@rocketsim.app + +## Key Features + +- Professional screenshot and video capture with device bezels +- Network traffic monitoring and debugging +- Push notification and deep link testing +- Design comparison with pixel-perfect overlays +- Accessibility testing (Dynamic Type, VoiceOver Navigator) +- Xcode build insights and team analytics +- Network speed throttling and Simulator airplane mode + +## Context + +- [Product context](https://www.rocketsim.app/llms-ctx.txt): concise product overview, feature summary, and technical details for RocketSim + +## Documentation Sets + +- [Abridged documentation](https://www.rocketsim.app/llms-small.txt): compact version with non-essential content removed +- [Complete documentation](https://www.rocketsim.app/llms-full.txt): full documentation for RocketSim + +## Quick Start + +- [Getting Started](https://www.rocketsim.app/docs/getting-started/onboarding) +- [Product Tour](https://www.rocketsim.app/docs/getting-started/product-tour-and-quick-demos) +- [FAQ](https://www.rocketsim.app/docs/support/faq) + +## Notes + +- All documentation is automatically generated from the same source as the official docs +- The "Last updated" date reflects when the documentation was last built and deployed +`; + await writeFile(llmsTxtPath, enhancedLlmsTxt, "utf-8"); + } catch { + // File might not exist + } +} + +function addRelatedLinks(page: string): string { + const titleMatch = page.match(/^# (.+)/); + if (!titleMatch) return page; + const title = titleMatch[1].trim(); + + const related = RELATED_LINKS[title]; + if (related && related.length > 0) { + return ( + page.trimEnd() + + "\n\n### Related\n" + + related.map((r) => `- ${r}`).join("\n") + + "\n" + ); + } + return page; +} + function transformLlmsTxt(content: string, variant: "full" | "small"): string { - // Preserve the header + // Extract and discard the original header const systemMatch = content.match(/^([\s\S]*?<\/SYSTEM>\n\n)/); - const systemHeader = systemMatch?.[1] ?? ""; - const body = systemHeader ? content.slice(systemHeader.length) : content; + const body = systemMatch ? content.slice(systemMatch[1].length) : content; // Split into page sections (each starts with "# Title") const pages = body.split(/(?=^# )/m); @@ -66,7 +298,18 @@ function transformLlmsTxt(content: string, variant: "full" | "small"): string { return true; }); - let result = systemHeader + filteredPages.join(""); + // Add cross-reference links to relevant pages + const pagesWithRelated = filteredPages.map(addRelatedLinks); + + // Assemble with enriched SYSTEM header and TOC + const newSystemHeader = + variant === "full" ? FULL_SYSTEM_HEADER : SMALL_SYSTEM_HEADER; + let result = + newSystemHeader + + "\n\n" + + TABLE_OF_CONTENTS + + "\n\n" + + pagesWithRelated.join(""); // Convert components to markdown links (handles multi-line tags) result = result.replace(//g, (match) => { @@ -101,9 +344,9 @@ function transformLlmsTxt(content: string, variant: "full" | "small"): string { // Convert to blockquotes result = result.replace( /^:::(tip|note|caution|danger)\n([\s\S]*?)^:::/gm, - (_match, type: string, content: string) => { + (_match, type: string, contentBlock: string) => { const label = type.charAt(0).toUpperCase() + type.slice(1); - const quoted = content + const quoted = contentBlock .trimEnd() .split("\n") .map((line) => `> ${line}`) From 8a88f12a66e40fad4fa5265e59dad44d37da5e31 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:54:49 +0100 Subject: [PATCH 2/4] Fix TOC title mismatches, Testimonials variant handling, and distribution wording Address Copilot review feedback: - Align TOC entries with actual page titles: "Setting up" (lowercase), "Statusbar Appearance" (one word), "Deeplinks (Universal Links)" - Fix RELATED_LINKS key for "Setting up RocketSim Connect" so cross-references actually match - Exclude Testimonials from TOC in small variant since the page is stripped - Soften distribution claim in llms-ctx.txt to match FAQ wording --- docs/public/llms-ctx.txt | 2 +- docs/src/integrations/llms-txt-post-process.ts | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/public/llms-ctx.txt b/docs/public/llms-ctx.txt index e541b74b..113eb5d7 100644 --- a/docs/public/llms-ctx.txt +++ b/docs/public/llms-ctx.txt @@ -31,7 +31,7 @@ User Defaults real-time editor, status bar customization, simulator camera suppo ## Technical Details - Platform: macOS (enhances the iOS/watchOS/visionOS Simulator in Xcode) -- Distribution: Mac App Store + direct enterprise distribution +- Distribution: Mac App Store (out-of-store distribution available on request — contact support@rocketsim.app) - Sandboxed: Yes - RocketSim Connect: Local Bonjour-based framework for Simulator-to-RocketSim communication (debug builds only) diff --git a/docs/src/integrations/llms-txt-post-process.ts b/docs/src/integrations/llms-txt-post-process.ts index e51abae4..0bdff6d5 100644 --- a/docs/src/integrations/llms-txt-post-process.ts +++ b/docs/src/integrations/llms-txt-post-process.ts @@ -43,7 +43,7 @@ const TABLE_OF_CONTENTS = `## Table of Contents - Onboarding - Product Tour & Quick Demos - Configuring App Actions -- Setting Up RocketSim Connect +- Setting up RocketSim Connect - How Large Teams Use RocketSim - Additional Resources - Testimonials @@ -60,7 +60,7 @@ const TABLE_OF_CONTENTS = `## Table of Contents - Simulator Camera Support ### Status Bar -- Status Bar Appearance +- Statusbar Appearance ### Design Comparison - Comparing Designs @@ -70,7 +70,7 @@ const TABLE_OF_CONTENTS = `## Table of Contents ### App Actions - App Directory Access -- Deep Links & Universal Links +- Deeplinks (Universal Links) - Location Simulation - Privacy & Permissions - Push Notifications @@ -156,7 +156,7 @@ const RELATED_LINKS: Record = { "Simulator Camera Support": [ "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", ], - "Setting Up RocketSim Connect": [ + "Setting up RocketSim Connect": [ "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", "[Simulator Camera Support](/docs/features/capturing/simulator-camera-support)", ], @@ -304,10 +304,15 @@ function transformLlmsTxt(content: string, variant: "full" | "small"): string { // Assemble with enriched SYSTEM header and TOC const newSystemHeader = variant === "full" ? FULL_SYSTEM_HEADER : SMALL_SYSTEM_HEADER; + let toc = TABLE_OF_CONTENTS; + if (variant === "small") { + toc = toc.replace(/^- Testimonials\n?/m, ""); + } + let result = newSystemHeader + "\n\n" + - TABLE_OF_CONTENTS + + toc + "\n\n" + pagesWithRelated.join(""); From 2049d686e91694008d4c1c51d7567c14d83dd949 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Mon, 2 Mar 2026 10:57:29 +0100 Subject: [PATCH 3/4] Fix Prettier formatting in llms-txt-post-process.ts --- docs/src/integrations/llms-txt-post-process.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/src/integrations/llms-txt-post-process.ts b/docs/src/integrations/llms-txt-post-process.ts index 0bdff6d5..f762bde0 100644 --- a/docs/src/integrations/llms-txt-post-process.ts +++ b/docs/src/integrations/llms-txt-post-process.ts @@ -310,11 +310,7 @@ function transformLlmsTxt(content: string, variant: "full" | "small"): string { } let result = - newSystemHeader + - "\n\n" + - toc + - "\n\n" + - pagesWithRelated.join(""); + newSystemHeader + "\n\n" + toc + "\n\n" + pagesWithRelated.join(""); // Convert components to markdown links (handles multi-line tags) result = result.replace(//g, (match) => { From 664aa5092cd748f60540c154ce5e2d401f0877d9 Mon Sep 17 00:00:00 2001 From: Antoine van der Lee <4329185+AvdLee@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:40:13 +0100 Subject: [PATCH 4/4] Automate TOC and related links, use config for base URL Address PR review feedback from ngnijland: - Replace hard-coded TABLE_OF_CONTENTS with dynamic generation that scans content files and groups them using the sidebar configuration - Replace hard-coded RELATED_LINKS with automatic generation based on sidebar grouping (pages in the same group link to siblings) - Extract sidebar group definitions into shared config used by both astro.config.ts and the post-processing integration - Derive base URL from config.json instead of hard-coding it (Copilot review feedback) --- docs/astro.config.ts | 85 +---- docs/src/config/sidebar-groups.ts | 75 ++++ .../src/integrations/llms-txt-post-process.ts | 358 ++++++++++-------- 3 files changed, 290 insertions(+), 228 deletions(-) create mode 100644 docs/src/config/sidebar-groups.ts diff --git a/docs/astro.config.ts b/docs/astro.config.ts index 2a446f01..67877f66 100644 --- a/docs/astro.config.ts +++ b/docs/astro.config.ts @@ -11,6 +11,7 @@ import sitemap from "@astrojs/sitemap"; import { llmsTxtPostProcess } from "./src/integrations/llms-txt-post-process"; import config from "./src/config/config.json"; +import { sidebarGroups } from "./src/config/sidebar-groups"; // https://astro.build/config export default defineConfig({ @@ -120,72 +121,24 @@ export default defineConfig({ Footer: "./src/components/starlight/Footer.astro", SiteTitle: "./src/components/starlight/SiteTitle.astro", }, - sidebar: [ - { - label: "Getting Started", - collapsed: true, - autogenerate: { directory: "docs/getting-started" }, - }, - { - label: "Screenshots & Recordings", - collapsed: true, - items: [ - { slug: "docs/features/capturing/screenshots" }, - { slug: "docs/features/capturing/recordings" }, - { slug: "docs/features/capturing/floating-thumbnail" }, - { slug: "docs/features/capturing/app-store-connect-optimization" }, - { slug: "docs/features/capturing/touch-indicators" }, - { slug: "docs/features/capturing/120-fps-recordings" }, - ], - }, - { - label: "Simulator Camera", - link: "/docs/features/capturing/simulator-camera-support", - }, - { - label: "Status Bar", - link: "/docs/features/capturing/statusbar-appearance", - }, - { - label: "Design Comparison", - collapsed: true, - autogenerate: { directory: "docs/features/design-comparison" }, - }, - { - label: "App Actions", - collapsed: true, - autogenerate: { directory: "docs/features/app-actions" }, - }, - { - label: "Networking", - collapsed: true, - autogenerate: { directory: "docs/features/networking" }, - }, - { - label: "Build Insights", - collapsed: true, - autogenerate: { directory: "docs/features/build-insights" }, - }, - { - label: "Accessibility", - collapsed: true, - autogenerate: { directory: "docs/features/accessibility" }, - }, - { - label: "User Defaults Editor", - link: "/docs/features/user-defaults-editor", - }, - { - label: "Settings", - collapsed: true, - autogenerate: { directory: "docs/settings" }, - }, - { - label: "Support", - collapsed: true, - autogenerate: { directory: "docs/support" }, - }, - ], + sidebar: sidebarGroups.map((group) => { + if (group.directory) { + return { + label: group.label, + collapsed: group.collapsed, + autogenerate: { directory: group.directory }, + }; + } + const slugs = group.slugs!; + if (slugs.length === 1) { + return { label: group.label, link: `/${slugs[0]}` }; + } + return { + label: group.label, + collapsed: group.collapsed, + items: slugs.map((slug) => ({ slug })), + }; + }), }), mdx(), llmsTxtPostProcess(), diff --git a/docs/src/config/sidebar-groups.ts b/docs/src/config/sidebar-groups.ts new file mode 100644 index 00000000..d82a4aed --- /dev/null +++ b/docs/src/config/sidebar-groups.ts @@ -0,0 +1,75 @@ +interface SidebarGroupDef { + label: string; + collapsed?: boolean; + /** For autogenerate groups: directory relative to the content collection root */ + directory?: string; + /** For explicit item/link groups: slug paths relative to the content collection root */ + slugs?: string[]; +} + +export const sidebarGroups: SidebarGroupDef[] = [ + { + label: "Getting Started", + collapsed: true, + directory: "docs/getting-started", + }, + { + label: "Screenshots & Recordings", + collapsed: true, + slugs: [ + "docs/features/capturing/screenshots", + "docs/features/capturing/recordings", + "docs/features/capturing/floating-thumbnail", + "docs/features/capturing/app-store-connect-optimization", + "docs/features/capturing/touch-indicators", + "docs/features/capturing/120-fps-recordings", + ], + }, + { + label: "Simulator Camera", + slugs: ["docs/features/capturing/simulator-camera-support"], + }, + { + label: "Status Bar", + slugs: ["docs/features/capturing/statusbar-appearance"], + }, + { + label: "Design Comparison", + collapsed: true, + directory: "docs/features/design-comparison", + }, + { + label: "App Actions", + collapsed: true, + directory: "docs/features/app-actions", + }, + { + label: "Networking", + collapsed: true, + directory: "docs/features/networking", + }, + { + label: "Build Insights", + collapsed: true, + directory: "docs/features/build-insights", + }, + { + label: "Accessibility", + collapsed: true, + directory: "docs/features/accessibility", + }, + { + label: "User Defaults Editor", + slugs: ["docs/features/user-defaults-editor"], + }, + { + label: "Settings", + collapsed: true, + directory: "docs/settings", + }, + { + label: "Support", + collapsed: true, + directory: "docs/support", + }, +]; diff --git a/docs/src/integrations/llms-txt-post-process.ts b/docs/src/integrations/llms-txt-post-process.ts index f762bde0..b340baaa 100644 --- a/docs/src/integrations/llms-txt-post-process.ts +++ b/docs/src/integrations/llms-txt-post-process.ts @@ -1,14 +1,25 @@ import type { AstroIntegration } from "astro"; -import { readFile, writeFile } from "node:fs/promises"; +import { readFile, readdir, writeFile } from "node:fs/promises"; import { fileURLToPath } from "node:url"; import path from "node:path"; +import { sidebarGroups } from "../config/sidebar-groups"; +import siteConfig from "../config/config.json"; + +const baseUrl = siteConfig.site.base_url; + +interface PageInfo { + title: string; + slug: string; + order: number; + groupLabel: string; +} const FULL_SYSTEM_HEADER = ` This is the official documentation for RocketSim, a macOS developer tool that enhances Apple's iOS Simulator. Product: RocketSim — available on the Mac App Store Developer: Antoine van der Lee (https://www.avanderlee.com) -Website: https://www.rocketsim.app +Website: ${baseUrl} Supported platforms: iOS, macOS, watchOS, and visionOS development via the Simulator Key capabilities: @@ -32,141 +43,16 @@ This is a compact version of the official documentation for RocketSim, a macOS d Product: RocketSim — available on the Mac App Store Developer: Antoine van der Lee (https://www.avanderlee.com) -Website: https://www.rocketsim.app +Website: ${baseUrl} Supported platforms: iOS, macOS, watchOS, and visionOS development via the Simulator Target audience: iOS, macOS, watchOS, and visionOS developers using Xcode and the Simulator. `; -const TABLE_OF_CONTENTS = `## Table of Contents - -### Getting Started -- Onboarding -- Product Tour & Quick Demos -- Configuring App Actions -- Setting up RocketSim Connect -- How Large Teams Use RocketSim -- Additional Resources -- Testimonials - -### Screenshots & Recordings -- Taking Screenshots -- Creating Recordings -- Floating Thumbnail -- App Store Connect Optimization -- Touch Indicators -- 120 FPS Recordings - -### Simulator Camera -- Simulator Camera Support - -### Status Bar -- Statusbar Appearance - -### Design Comparison -- Comparing Designs -- Grids & Rulers -- Magnifier -- Slow Animations - -### App Actions -- App Directory Access -- Deeplinks (Universal Links) -- Location Simulation -- Privacy & Permissions -- Push Notifications -- Quick Actions - -### Networking -- Network Speed Control & Simulator Airplane Mode -- Network Traffic Monitoring -- Networking Insights - -### Build Insights -- Build Insights -- Team Build Insights - -### Accessibility -- Environment Overrides -- Toggles & Dynamic Text -- VoiceOver Navigator - -### Other Features -- User Defaults Editor - -### Settings -- Shortcuts -- Side Window - -### Support -- FAQ -- Reporting An Issue -- Requesting A Feature`; - -const RELATED_LINKS: Record = { - "Taking Screenshots": [ - "[Creating Recordings](/docs/features/capturing/recordings)", - "[App Store Connect Optimization](/docs/features/capturing/app-store-connect-optimization)", - "[Floating Thumbnail](/docs/features/capturing/floating-thumbnail)", - ], - "Creating Recordings": [ - "[Taking Screenshots](/docs/features/capturing/screenshots)", - "[Touch Indicators](/docs/features/capturing/touch-indicators)", - "[120 FPS Recordings](/docs/features/capturing/120-fps-recordings)", - ], - "Network Traffic Monitoring": [ - "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", - "[Networking Insights](/docs/features/networking/networking-insights)", - "[Network Speed Control](/docs/features/networking/network-speed-control)", - ], - "Networking Insights": [ - "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", - "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", - ], - "Network Speed Control & Simulator Airplane Mode": [ - "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", - "[Networking Insights](/docs/features/networking/networking-insights)", - ], - "Push Notifications": [ - "[Configuring App Actions](/docs/getting-started/configuring-app-actions)", - "[Deep Links & Universal Links](/docs/features/app-actions/deeplinks-universal-links)", - ], - "Deeplinks (Universal Links)": [ - "[Configuring App Actions](/docs/getting-started/configuring-app-actions)", - "[Push Notifications](/docs/features/app-actions/push-notifications)", - ], - "Build Insights": [ - "[Team Build Insights](/docs/features/build-insights/team-build-insights)", - ], - "Team Build Insights": [ - "[Build Insights](/docs/features/build-insights/build-insights)", - "[How Large Teams Use RocketSim](/docs/getting-started/how-large-teams-use-rocketsim)", - ], - "Comparing Designs": [ - "[Grids & Rulers](/docs/features/design-comparison/grids-and-rulers)", - "[Magnifier](/docs/features/design-comparison/magnifier)", - ], - "Environment Overrides": [ - "[Toggles & Dynamic Text](/docs/features/accessibility/toggles-and-dynamic-text)", - "[VoiceOver Navigator](/docs/features/accessibility/voiceover-navigator)", - ], - "VoiceOver Navigator": [ - "[Environment Overrides](/docs/features/accessibility/environment-overrides)", - "[Toggles & Dynamic Text](/docs/features/accessibility/toggles-and-dynamic-text)", - ], - "Simulator Camera Support": [ - "[Setting Up RocketSim Connect](/docs/getting-started/setting-up-rocketsim-connect)", - ], - "Setting up RocketSim Connect": [ - "[Network Traffic Monitoring](/docs/features/networking/network-traffic-monitoring)", - "[Simulator Camera Support](/docs/features/capturing/simulator-camera-support)", - ], -}; - /** * Post-processes the generated llms-full.txt and llms-small.txt files to: * - Replace the SYSTEM header with an enriched product context block - * - Inject a table of contents for navigation - * - Add cross-reference "Related" links between related pages + * - Inject an auto-generated table of contents derived from the sidebar config + * - Add cross-reference "Related" links between pages in the same sidebar group * - Remove the home/index page (only contains navigation components) * - Remove the 404 page * - Convert components to YouTube links @@ -185,6 +71,8 @@ export function llmsTxtPostProcess(): AstroIntegration { hooks: { "astro:build:done": async ({ dir }) => { const outputDir = fileURLToPath(dir); + const contentRoot = path.join(process.cwd(), "src/content/docs"); + const pages = await scanContentPages(contentRoot); const variants = [ { file: "llms-full.txt", variant: "full" as const }, @@ -195,7 +83,9 @@ export function llmsTxtPostProcess(): AstroIntegration { const filePath = path.join(outputDir, file); try { let content = await readFile(filePath, "utf-8"); - content = transformLlmsTxt(content, variant); + const toc = buildTableOfContents(pages, variant); + const relatedLinks = buildRelatedLinks(pages, variant); + content = transformLlmsTxt(content, variant, toc, relatedLinks); await writeFile(filePath, content, "utf-8"); } catch { // File might not exist, skip @@ -208,6 +98,164 @@ export function llmsTxtPostProcess(): AstroIntegration { }; } +async function scanContentPages(contentRoot: string): Promise { + const pages: PageInfo[] = []; + + for (const group of sidebarGroups) { + if (group.directory) { + const dirPath = path.join(contentRoot, group.directory); + let files: string[]; + try { + files = await readdir(dirPath); + } catch { + continue; + } + + for (const file of files.filter( + (f) => f.endsWith(".md") || f.endsWith(".mdx"), + )) { + const content = await readFile(path.join(dirPath, file), "utf-8"); + const fm = extractFrontmatter(content); + const slug = group.directory + "/" + file.replace(/\.(mdx?)$/, ""); + pages.push({ + title: fm.title, + slug, + order: fm.sidebarOrder ?? 999, + groupLabel: group.label, + }); + } + } else if (group.slugs) { + for (let i = 0; i < group.slugs.length; i++) { + const slug = group.slugs[i]; + const content = await readContentFile(contentRoot, slug); + if (!content) continue; + const fm = extractFrontmatter(content); + pages.push({ + title: fm.title, + slug, + order: i, + groupLabel: group.label, + }); + } + } + } + + return pages; +} + +async function readContentFile( + contentRoot: string, + slug: string, +): Promise { + for (const ext of [".md", ".mdx"]) { + try { + return await readFile(path.join(contentRoot, slug + ext), "utf-8"); + } catch { + continue; + } + } + return null; +} + +function extractFrontmatter(content: string): { + title: string; + sidebarOrder?: number; +} { + const fmMatch = content.match(/^---\n([\s\S]*?)\n---/); + if (!fmMatch) return { title: "" }; + const fm = fmMatch[1]; + const titleMatch = fm.match(/title:\s*"([^"]+)"/); + const orderMatch = fm.match(/order:\s*(\d+)/); + return { + title: titleMatch?.[1] ?? "", + sidebarOrder: orderMatch ? parseInt(orderMatch[1]) : undefined, + }; +} + +function buildTableOfContents( + pages: PageInfo[], + variant: "full" | "small", +): string { + const groupOrder = sidebarGroups.map((g) => g.label); + const grouped = new Map(); + + for (const label of groupOrder) { + grouped.set(label, []); + } + + for (const page of pages) { + if (variant === "small" && page.title === "Testimonials") continue; + grouped.get(page.groupLabel)?.push(page); + } + + let toc = "## Table of Contents\n"; + + for (const label of groupOrder) { + const groupPages = grouped.get(label); + if (!groupPages || groupPages.length === 0) continue; + + groupPages.sort((a, b) => a.order - b.order); + + toc += `\n### ${label}\n`; + for (const page of groupPages) { + toc += `- ${page.title}\n`; + } + } + + return toc.trimEnd(); +} + +function buildRelatedLinks( + pages: PageInfo[], + variant: "full" | "small", +): Record { + const filtered = + variant === "small" + ? pages.filter((p) => p.title !== "Testimonials") + : pages; + const grouped = new Map(); + for (const page of filtered) { + if (!grouped.has(page.groupLabel)) { + grouped.set(page.groupLabel, []); + } + grouped.get(page.groupLabel)!.push(page); + } + + const related: Record = {}; + + for (const groupPages of grouped.values()) { + if (groupPages.length < 2) continue; + + for (const page of groupPages) { + related[page.title] = groupPages + .filter((p) => p.slug !== page.slug) + .map((p) => `[${p.title}](/${p.slug})`); + } + } + + return related; +} + +function addRelatedLinks( + page: string, + relatedLinks: Record, +): string { + const titleMatch = page.match(/^# (.+)/); + if (!titleMatch) return page; + const title = titleMatch[1].trim(); + + const related = relatedLinks[title]; + if (related && related.length > 0) { + return ( + page.trimEnd() + + "\n\n### Related\n" + + related.map((r) => `- ${r}`).join("\n") + + "\n" + ); + } + return page; +} + async function enhanceLlmsTxtIndex(outputDir: string): Promise { const llmsTxtPath = path.join(outputDir, "llms.txt"); try { @@ -217,8 +265,8 @@ async function enhanceLlmsTxtIndex(outputDir: string): Promise { > RocketSim is a macOS developer tool that enhances Apple's iOS Simulator with professional-grade features for capturing, debugging, testing, and design validation. Available on the Mac App Store for iOS, macOS, watchOS, and visionOS developers. Last updated: ${buildDate} -Website: https://www.rocketsim.app -Documentation: https://www.rocketsim.app/docs +Website: ${baseUrl} +Documentation: ${baseUrl}/docs GitHub: https://github.com/AvdLee/RocketSimApp Support: support@rocketsim.app @@ -234,18 +282,18 @@ Support: support@rocketsim.app ## Context -- [Product context](https://www.rocketsim.app/llms-ctx.txt): concise product overview, feature summary, and technical details for RocketSim +- [Product context](${baseUrl}/llms-ctx.txt): concise product overview, feature summary, and technical details for RocketSim ## Documentation Sets -- [Abridged documentation](https://www.rocketsim.app/llms-small.txt): compact version with non-essential content removed -- [Complete documentation](https://www.rocketsim.app/llms-full.txt): full documentation for RocketSim +- [Abridged documentation](${baseUrl}/llms-small.txt): compact version with non-essential content removed +- [Complete documentation](${baseUrl}/llms-full.txt): full documentation for RocketSim ## Quick Start -- [Getting Started](https://www.rocketsim.app/docs/getting-started/onboarding) -- [Product Tour](https://www.rocketsim.app/docs/getting-started/product-tour-and-quick-demos) -- [FAQ](https://www.rocketsim.app/docs/support/faq) +- [Getting Started](${baseUrl}/docs/getting-started/onboarding) +- [Product Tour](${baseUrl}/docs/getting-started/product-tour-and-quick-demos) +- [FAQ](${baseUrl}/docs/support/faq) ## Notes @@ -258,24 +306,12 @@ Support: support@rocketsim.app } } -function addRelatedLinks(page: string): string { - const titleMatch = page.match(/^# (.+)/); - if (!titleMatch) return page; - const title = titleMatch[1].trim(); - - const related = RELATED_LINKS[title]; - if (related && related.length > 0) { - return ( - page.trimEnd() + - "\n\n### Related\n" + - related.map((r) => `- ${r}`).join("\n") + - "\n" - ); - } - return page; -} - -function transformLlmsTxt(content: string, variant: "full" | "small"): string { +function transformLlmsTxt( + content: string, + variant: "full" | "small", + toc: string, + relatedLinks: Record, +): string { // Extract and discard the original header const systemMatch = content.match(/^([\s\S]*?<\/SYSTEM>\n\n)/); const body = systemMatch ? content.slice(systemMatch[1].length) : content; @@ -299,15 +335,13 @@ function transformLlmsTxt(content: string, variant: "full" | "small"): string { }); // Add cross-reference links to relevant pages - const pagesWithRelated = filteredPages.map(addRelatedLinks); + const pagesWithRelated = filteredPages.map((page) => + addRelatedLinks(page, relatedLinks), + ); // Assemble with enriched SYSTEM header and TOC const newSystemHeader = variant === "full" ? FULL_SYSTEM_HEADER : SMALL_SYSTEM_HEADER; - let toc = TABLE_OF_CONTENTS; - if (variant === "small") { - toc = toc.replace(/^- Testimonials\n?/m, ""); - } let result = newSystemHeader + "\n\n" + toc + "\n\n" + pagesWithRelated.join("");