@shoalrun/cli 0.1.0-alpha.11 → 0.1.0-alpha.13

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.
Files changed (602) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +59 -17
  3. package/agent-docs/.well-known/shoalrun/navigation/examples-tab-50f26fe22670.txt +22 -0
  4. package/agent-docs/.well-known/shoalrun/navigation/project-updates-50f26fe22670.txt +33 -3
  5. package/agent-docs/.well-known/shoalrun/navigation/reference-tab-50f26fe22670.txt +22 -0
  6. package/agent-docs/SNAPSHOT.json +5 -5
  7. package/agent-docs/api-docs/focused-contracts.md +2 -2
  8. package/agent-docs/api-docs/generate.md +6 -6
  9. package/agent-docs/api-docs/generate.sections/add-useful-examples.md +2 -2
  10. package/agent-docs/api-docs/generate.sections/choose-generated-references-or-mdx.md +5 -5
  11. package/agent-docs/api-docs/generate.sections/describe-filters-that-do-not-use-their-openapi-parameter-name.md +2 -2
  12. package/agent-docs/api-docs/generate.sections/generate-many-pages-selectively.md +2 -2
  13. package/agent-docs/api-docs/generate.sections/link-guides-to-api-references.md +2 -2
  14. package/agent-docs/api-docs/generate.sections/map-extension-values-to-shoalrun-status.md +2 -2
  15. package/agent-docs/api-docs/generate.sections/override-generated-reference-order-in-navigation.md +3 -3
  16. package/agent-docs/api-docs/generate.sections/related-reading.md +2 -2
  17. package/agent-docs/api-docs/generate.sections/use-a-template-for-editorial-context.md +2 -2
  18. package/agent-docs/api-docs/support.md +14 -13
  19. package/agent-docs/author/add-page.md +8 -6
  20. package/agent-docs/author/agent-overview.md +1 -1
  21. package/agent-docs/author/agent-workflow.md +1 -1
  22. package/agent-docs/author/analytics.md +1 -1
  23. package/agent-docs/author/analytics.sections/adapter-exports-and-consent.md +1 -1
  24. package/agent-docs/author/analytics.sections/built-in-events.md +1 -1
  25. package/agent-docs/author/analytics.sections/configure-an-adapter.md +1 -1
  26. package/agent-docs/author/analytics.sections/custom-interactions.md +1 -1
  27. package/agent-docs/author/analytics.sections/event-format.md +1 -1
  28. package/agent-docs/author/analytics.sections/html-markdown-and-agents.md +1 -1
  29. package/agent-docs/author/analytics.sections/inspect-events-locally.md +1 -1
  30. package/agent-docs/author/analytics.sections/map-events-to-your-service.md +1 -1
  31. package/agent-docs/author/analytics.sections/posthog-example.md +1 -1
  32. package/agent-docs/author/analytics.sections/related-reading.md +1 -1
  33. package/agent-docs/author/authoring-agent.md +1 -1
  34. package/agent-docs/author/coding-agent.md +1 -1
  35. package/agent-docs/author/components/action-link.md +9 -3
  36. package/agent-docs/author/components/api-embeds.md +11 -3
  37. package/agent-docs/author/components/api-embeds.sections/apiexample.md +7 -3
  38. package/agent-docs/author/components/api-embeds.sections/html-markdown-and-agents.md +3 -3
  39. package/agent-docs/author/components/api-embeds.sections/related-reading.md +3 -3
  40. package/agent-docs/author/components/badge.md +8 -4
  41. package/agent-docs/author/components/breadcrumbs.md +1 -1
  42. package/agent-docs/author/components/callout.md +8 -4
  43. package/agent-docs/author/components/cards.md +2 -2
  44. package/agent-docs/author/components/cards.sections/add-a-lucide-icon.md +2 -2
  45. package/agent-docs/author/components/cards.sections/build-a-collection.md +2 -2
  46. package/agent-docs/author/components/cards.sections/curate-a-reading-list.md +2 -2
  47. package/agent-docs/author/components/cards.sections/html-markdown-and-agents.md +2 -2
  48. package/agent-docs/author/components/cards.sections/link-to-one-document.md +2 -2
  49. package/agent-docs/author/components/cards.sections/override-card-text.md +2 -2
  50. package/agent-docs/author/components/cards.sections/related-reading.md +2 -2
  51. package/agent-docs/author/components/code-blocks.md +8 -4
  52. package/agent-docs/author/components/collapsible.md +7 -3
  53. package/agent-docs/author/components/cookbook-chooser.md +7 -3
  54. package/agent-docs/author/components/custom/react.md +1 -1
  55. package/agent-docs/author/components/custom/react.sections/html-markdown-and-agents.md +1 -1
  56. package/agent-docs/author/components/custom/react.sections/interactive-react-example.md +1 -1
  57. package/agent-docs/author/components/custom/react.sections/registration.md +1 -1
  58. package/agent-docs/author/components/custom/react.sections/related-reading.md +1 -1
  59. package/agent-docs/author/components/custom/react.sections/share-the-model-with-the-browser.md +1 -1
  60. package/agent-docs/author/components/custom/react.sections/where-the-content-lives.md +1 -1
  61. package/agent-docs/author/components/custom.md +1 -1
  62. package/agent-docs/author/components/definition-list.md +5 -3
  63. package/agent-docs/author/components/diagrams/d2-gallery.md +2 -2
  64. package/agent-docs/author/components/diagrams/d2-gallery.sections/basic-shapes.md +2 -2
  65. package/agent-docs/author/components/diagrams/d2-gallery.sections/flows-and-structures.md +2 -2
  66. package/agent-docs/author/components/diagrams/d2-gallery.sections/html-markdown-and-agents.md +2 -2
  67. package/agent-docs/author/components/diagrams/d2-gallery.sections/layout-engines.md +2 -2
  68. package/agent-docs/author/components/diagrams/d2-gallery.sections/related-reading.md +2 -2
  69. package/agent-docs/author/components/diagrams/d2-gallery.sections/sequences-and-grids.md +2 -2
  70. package/agent-docs/author/components/diagrams/d2-gallery.sections/styles-and-code.md +2 -2
  71. package/agent-docs/author/components/diagrams/pele-gallery.md +2 -2
  72. package/agent-docs/author/components/diagrams/pele-gallery.sections/charts-and-planning.md +2 -2
  73. package/agent-docs/author/components/diagrams/pele-gallery.sections/flowchart-shapes.md +2 -2
  74. package/agent-docs/author/components/diagrams/pele-gallery.sections/flows-and-behavior.md +2 -2
  75. package/agent-docs/author/components/diagrams/pele-gallery.sections/html-markdown-and-agents.md +2 -2
  76. package/agent-docs/author/components/diagrams/pele-gallery.sections/related-reading.md +2 -2
  77. package/agent-docs/author/components/diagrams/pele-gallery.sections/specialized-diagrams.md +2 -2
  78. package/agent-docs/author/components/diagrams/pele-gallery.sections/systems-and-structures.md +2 -2
  79. package/agent-docs/author/components/diagrams.md +13 -5
  80. package/agent-docs/author/components/doc-link.md +7 -3
  81. package/agent-docs/author/components/fields.md +6 -4
  82. package/agent-docs/author/components/file-tree.md +7 -3
  83. package/agent-docs/author/components/images.md +5 -3
  84. package/agent-docs/author/components/info-hint.md +7 -3
  85. package/agent-docs/author/components/kbd.md +5 -3
  86. package/agent-docs/author/components/math.md +7 -3
  87. package/agent-docs/author/components/only.md +9 -5
  88. package/agent-docs/author/components/progress.md +7 -3
  89. package/agent-docs/author/components/related-reading.md +7 -3
  90. package/agent-docs/author/components/steps.md +9 -3
  91. package/agent-docs/author/components/tables.md +7 -3
  92. package/agent-docs/author/components/tabs.md +7 -3
  93. package/agent-docs/author/components/timeline.md +10 -4
  94. package/agent-docs/author/components/tooltips.md +7 -3
  95. package/agent-docs/author/components/walkthroughs.md +5 -3
  96. package/agent-docs/author/components/walkthroughs.sections/attributes.md +3 -3
  97. package/agent-docs/author/components/walkthroughs.sections/build-up-code.md +3 -3
  98. package/agent-docs/author/components/walkthroughs.sections/choose-a-layout.md +3 -3
  99. package/agent-docs/author/components/walkthroughs.sections/explain-one-file.md +3 -3
  100. package/agent-docs/author/components/walkthroughs.sections/html-markdown-and-agents.md +3 -3
  101. package/agent-docs/author/components/walkthroughs.sections/related-reading.md +3 -3
  102. package/agent-docs/author/components/walkthroughs.sections/syntax.md +51 -0
  103. package/agent-docs/author/components/walkthroughs.sections/take-code-from-a-file.md +3 -22
  104. package/agent-docs/author/components.md +19 -4
  105. package/agent-docs/author/css.md +13 -10
  106. package/agent-docs/author/css.sections/borders-fields-and-navigation-tokens.md +3 -3
  107. package/agent-docs/author/css.sections/core-color-tokens.md +3 -3
  108. package/agent-docs/author/css.sections/html-markdown-and-agents.md +54 -0
  109. package/agent-docs/author/css.sections/page-attributes.md +9 -9
  110. package/agent-docs/author/css.sections/page-transitions.md +3 -3
  111. package/agent-docs/author/css.sections/responsive-behavior.md +3 -3
  112. package/agent-docs/author/css.sections/status-code-and-callout-tokens.md +3 -3
  113. package/agent-docs/author/css.sections/typography-shape-and-width-tokens.md +3 -3
  114. package/agent-docs/author/custom-metadata.md +2 -2
  115. package/agent-docs/author/custom-metadata.sections/add-a-custom-page-field.md +2 -2
  116. package/agent-docs/author/custom-metadata.sections/choose-text-for-each-surface.md +2 -2
  117. package/agent-docs/author/custom-metadata.sections/preview-changes-to-metadata-providers.md +2 -2
  118. package/agent-docs/author/custom-metadata.sections/read-metadata-from-a-project-module.md +2 -2
  119. package/agent-docs/author/custom-metadata.sections/related-reading.md +2 -2
  120. package/agent-docs/author/design-templates.md +1 -1
  121. package/agent-docs/author/design-writing-guides.md +1 -1
  122. package/agent-docs/author/frontmatter-reference.md +34 -27
  123. package/agent-docs/author/frontmatter-reference.sections/choose-a-publication-and-visibility.md +5 -3
  124. package/agent-docs/author/frontmatter-reference.sections/control-output-details.md +5 -3
  125. package/agent-docs/author/frontmatter-reference.sections/global-defaults-and-enforced-values.md +5 -3
  126. package/agent-docs/author/frontmatter-reference.sections/html-markdown-and-agents.md +33 -0
  127. package/agent-docs/author/frontmatter-reference.sections/identify-and-route-a-page.md +5 -3
  128. package/agent-docs/author/frontmatter-reference.sections/point-agents-to-it.md +5 -3
  129. package/agent-docs/author/frontmatter-reference.sections/project-defined-fields.md +5 -3
  130. package/agent-docs/author/frontmatter-reference.sections/related-reading.md +5 -3
  131. package/agent-docs/author/frontmatter-reference.sections/use-the-local-files-while-authoring.md +5 -3
  132. package/agent-docs/author/frontmatter-reference.sections/when-the-files-update.md +5 -3
  133. package/agent-docs/author/frontmatter.md +7 -4
  134. package/agent-docs/author/frontmatter.sections/audience-badges.md +3 -3
  135. package/agent-docs/author/frontmatter.sections/give-deprecation-guidance.md +3 -3
  136. package/agent-docs/author/frontmatter.sections/global-defaults-and-enforced-values.md +3 -3
  137. package/agent-docs/author/frontmatter.sections/optional-native-fields.md +7 -4
  138. package/agent-docs/author/frontmatter.sections/publication-fields.md +3 -3
  139. package/agent-docs/author/frontmatter.sections/publishing-policy.md +3 -3
  140. package/agent-docs/author/frontmatter.sections/related-metadata-tasks.md +3 -3
  141. package/agent-docs/author/frontmatter.sections/related-reading.md +3 -3
  142. package/agent-docs/author/frontmatter.sections/required-after-inheritance.md +3 -3
  143. package/agent-docs/author/frontmatter.sections/seo-fields.md +3 -3
  144. package/agent-docs/author/frontmatter.sections/validation-rules.md +3 -3
  145. package/agent-docs/author/markdown-metadata.md +17 -9
  146. package/agent-docs/author/navigation.md +13 -2
  147. package/agent-docs/author/navigation.sections/arrange-authored-pages.md +2 -2
  148. package/agent-docs/author/navigation.sections/fill-an-api-tag-group.md +2 -2
  149. package/agent-docs/author/navigation.sections/hide-group-page-counts.md +13 -2
  150. package/agent-docs/author/navigation.sections/html-markdown-and-agents.md +2 -2
  151. package/agent-docs/author/navigation.sections/local-api-preview.md +2 -2
  152. package/agent-docs/author/navigation.sections/mix-guides-and-api-references.md +2 -2
  153. package/agent-docs/author/navigation.sections/optionally-split-a-large-menu-into-files.md +2 -2
  154. package/agent-docs/author/navigation.sections/reach-navigation-while-reading.md +2 -2
  155. package/agent-docs/author/navigation.sections/related-reading.md +2 -2
  156. package/agent-docs/author/navigation.sections/split-navigation-into-tabs.md +2 -2
  157. package/agent-docs/author/navigation.sections/subject-lifecycle-labels.md +2 -2
  158. package/agent-docs/author/recipe-drafts.md +16 -16
  159. package/agent-docs/author/recipe-drafts.sections/1-write-one-reusable-step.md +5 -5
  160. package/agent-docs/author/recipe-drafts.sections/2-list-the-steps-for-one-complete-goal.md +3 -3
  161. package/agent-docs/author/recipe-drafts.sections/3-generate-a-draft-and-review-it.md +4 -4
  162. package/agent-docs/author/recipe-drafts.sections/4-maintain-shoalrun-s-published-recipe-snapshots.md +3 -3
  163. package/agent-docs/author/recipe-drafts.sections/related-reading.md +1 -1
  164. package/agent-docs/author/recipe-drafts.sections/start-an-ingredient-from-an-api-example.md +5 -5
  165. package/agent-docs/author/recipes.md +4 -4
  166. package/agent-docs/author/recipes.sections/how-agents-use-this.md +1 -1
  167. package/agent-docs/author/recipes.sections/one-example-from-shoalrun.md +4 -4
  168. package/agent-docs/author/recipes.sections/related-reading.md +1 -1
  169. package/agent-docs/author/recipes.sections/try-a-complete-workflow.md +1 -1
  170. package/agent-docs/author/recipes.sections/use-recipes-for-task-oriented-how-tos.md +1 -1
  171. package/agent-docs/author/recipes.sections/what-changing-an-ingredient-updates.md +1 -1
  172. package/agent-docs/author/recipes.sections/what-each-file-does.md +1 -1
  173. package/agent-docs/author/recipes.sections/what-happens-and-when.md +1 -1
  174. package/agent-docs/author/related-reading.md +5 -1
  175. package/agent-docs/author/related-reading.sections/automatic-footers.md +1 -1
  176. package/agent-docs/author/related-reading.sections/declare-relationships.md +1 -1
  177. package/agent-docs/author/related-reading.sections/display-related-documents.md +1 -1
  178. package/agent-docs/author/related-reading.sections/html-markdown-and-agents.md +28 -0
  179. package/agent-docs/author/related-reading.sections/inspect-output-and-changes.md +1 -1
  180. package/agent-docs/author/related-reading.sections/reading-paths-in-section-markdown.md +1 -1
  181. package/agent-docs/author/related-reading.sections/related-reading.md +1 -1
  182. package/agent-docs/author/related-reading.sections/where-relationship-explanations-come-from.md +1 -1
  183. package/agent-docs/author/search.md +1 -1
  184. package/agent-docs/author/search.sections/choose-a-provider.md +1 -1
  185. package/agent-docs/author/search.sections/cli-and-mcp-ranking-details.md +1 -1
  186. package/agent-docs/author/search.sections/hosted-semantic-search-limits.md +1 -1
  187. package/agent-docs/author/search.sections/html-markdown-and-agents.md +1 -1
  188. package/agent-docs/author/search.sections/lexical-search.md +1 -1
  189. package/agent-docs/author/search.sections/local-semantic-preview.md +1 -1
  190. package/agent-docs/author/search.sections/read-a-search-result-with-an-agent.md +1 -1
  191. package/agent-docs/author/search.sections/related-reading.md +1 -1
  192. package/agent-docs/author/search.sections/reuse-the-lexical-index.md +1 -1
  193. package/agent-docs/author/search.sections/turn-search-off.md +1 -1
  194. package/agent-docs/author/search.sections/use-the-search-box.md +1 -1
  195. package/agent-docs/author/search.sections/write-a-custom-provider.md +1 -1
  196. package/agent-docs/author/snippets.md +5 -1
  197. package/agent-docs/author/taxonomy.md +1 -1
  198. package/agent-docs/author/templates.md +16 -8
  199. package/agent-docs/author/templates.sections/built-in-feature-templates.md +3 -3
  200. package/agent-docs/author/templates.sections/built-in-templates.md +3 -3
  201. package/agent-docs/author/templates.sections/choose-formatting-enforcement-for-your-project.md +3 -3
  202. package/agent-docs/author/templates.sections/create-or-edit-a-project-template.md +12 -4
  203. package/agent-docs/author/templates.sections/keep-the-four-shapes-distinct.md +3 -3
  204. package/agent-docs/author/templates.sections/project-added-templates.md +3 -3
  205. package/agent-docs/author/templates.sections/related-reading.md +3 -3
  206. package/agent-docs/author/templates.sections/scaffold-a-page.md +7 -7
  207. package/agent-docs/author/templates.sections/short-cli-and-derived-values.md +3 -3
  208. package/agent-docs/author/templates.sections/what-every-template-gives-you.md +3 -3
  209. package/agent-docs/author/workspace/commands.md +2 -2
  210. package/agent-docs/author/workspace.md +8 -2
  211. package/agent-docs/author/writing-style.md +27 -5
  212. package/agent-docs/author/writing-style.sections/adapt-this-example.md +3 -3
  213. package/agent-docs/author/writing-style.sections/choose-components-by-reader-need.md +6 -4
  214. package/agent-docs/author/writing-style.sections/evidence-and-uncertainty.md +3 -3
  215. package/agent-docs/author/writing-style.sections/example-audience-and-scope.md +3 -3
  216. package/agent-docs/author/writing-style.sections/feature-availability.md +36 -0
  217. package/agent-docs/author/writing-style.sections/ingredients-recipes-and-cookbooks.md +3 -3
  218. package/agent-docs/author/writing-style.sections/page-purpose-and-structure.md +12 -4
  219. package/agent-docs/author/writing-style.sections/procedures-and-examples.md +3 -3
  220. package/agent-docs/author/writing-style.sections/related-reading.md +3 -3
  221. package/agent-docs/author/writing-style.sections/review-a-draft.md +3 -3
  222. package/agent-docs/author/writing-style.sections/reviewed-writing-examples.md +3 -3
  223. package/agent-docs/author/writing-style.sections/voice-and-explanations.md +3 -3
  224. package/agent-docs/changelog/2026-10-14-agent-readiness.md +2 -2
  225. package/agent-docs/changelog/2026-10-15-evaluation-builds.md +2 -2
  226. package/agent-docs/changelog/2026-10-16-navigation-layouts.md +2 -2
  227. package/agent-docs/changelog/2026-10-17-mcp-hosting.md +2 -2
  228. package/agent-docs/changelog/2026-10-18-search-and-tooltips.md +2 -2
  229. package/agent-docs/changelog/2026-10-19-visual-navigation.md +2 -2
  230. package/agent-docs/changelog/2026-10-25.md +2 -2
  231. package/agent-docs/changelog/2026-10-26.md +2 -2
  232. package/agent-docs/changelog/2026-10-27.md +2 -2
  233. package/agent-docs/changelog/2026-10-28.md +89 -0
  234. package/agent-docs/changelog/authoring-preview.md +2 -2
  235. package/agent-docs/changelog/authoring-search.md +3 -3
  236. package/agent-docs/changelog/authoring-tools.md +2 -2
  237. package/agent-docs/changelog/working-tree-skill.md +2 -2
  238. package/agent-docs/changelog.md +11 -3
  239. package/agent-docs/chat/checks.md +1 -1
  240. package/agent-docs/chat/checks.sections/answer-ahead-of-time.md +1 -1
  241. package/agent-docs/chat/checks.sections/answer-for-one-audience.md +1 -1
  242. package/agent-docs/chat/checks.sections/answer-without-a-model.md +1 -1
  243. package/agent-docs/chat/checks.sections/follow-up-questions.md +1 -1
  244. package/agent-docs/chat/checks.sections/how-an-answer-is-checked.md +1 -1
  245. package/agent-docs/chat/checks.sections/questions-with-several-parts.md +1 -1
  246. package/agent-docs/chat/checks.sections/related-reading.md +1 -1
  247. package/agent-docs/chat/checks.sections/reuse-answers.md +1 -1
  248. package/agent-docs/chat/host.md +1 -1
  249. package/agent-docs/chat/host.sections/cap-the-daily-spend.md +1 -1
  250. package/agent-docs/chat/host.sections/keep-a-record-of-questions.md +1 -1
  251. package/agent-docs/chat/host.sections/related-reading.md +1 -1
  252. package/agent-docs/chat/passage-index.md +2 -2
  253. package/agent-docs/chat/passage-index.sections/build-the-index.md +2 -2
  254. package/agent-docs/chat/passage-index.sections/embed-passages.md +2 -2
  255. package/agent-docs/chat/passage-index.sections/how-the-default-chunker-splits-a-page.md +2 -2
  256. package/agent-docs/chat/passage-index.sections/limits.md +2 -2
  257. package/agent-docs/chat/passage-index.sections/passage-ids-and-links.md +2 -2
  258. package/agent-docs/chat/passage-index.sections/related-reading.md +2 -2
  259. package/agent-docs/chat/passage-index.sections/what-a-passage-contains.md +2 -2
  260. package/agent-docs/chat/prepared-answers.md +1 -1
  261. package/agent-docs/chat/settings.md +2 -2
  262. package/agent-docs/chat/settings.sections/choose-the-scorer.md +2 -2
  263. package/agent-docs/chat/settings.sections/configure-chat.md +2 -2
  264. package/agent-docs/chat/settings.sections/configure-retrieval.md +2 -2
  265. package/agent-docs/chat/settings.sections/related-reading.md +2 -2
  266. package/agent-docs/chat/settings.sections/send-extra-request-fields.md +2 -2
  267. package/agent-docs/chat/settings.sections/use-more-than-one-model.md +2 -2
  268. package/agent-docs/chat/settings.sections/when-the-scorer-is-down.md +2 -2
  269. package/agent-docs/chat/setup.md +1 -1
  270. package/agent-docs/chat.md +1 -1
  271. package/agent-docs/cli.md +2 -2
  272. package/agent-docs/cli.sections/audit-a-project-and-api-sources.md +2 -2
  273. package/agent-docs/cli.sections/author-pages.md +2 -2
  274. package/agent-docs/cli.sections/build-and-serve.md +2 -2
  275. package/agent-docs/cli.sections/inspect-config-and-operations.md +2 -2
  276. package/agent-docs/cli.sections/npm-scripts-in-this-repository.md +2 -2
  277. package/agent-docs/cli.sections/related-reading.md +2 -2
  278. package/agent-docs/cli.sections/search-and-chat.md +2 -2
  279. package/agent-docs/cli.sections/start-a-project.md +2 -2
  280. package/agent-docs/cli.sections/working-tree-authoring-tools.md +2 -2
  281. package/agent-docs/config/apis.md +2 -2
  282. package/agent-docs/config/content.md +2 -2
  283. package/agent-docs/config/content.sections/authoring.md +2 -2
  284. package/agent-docs/config/content.sections/badges.md +2 -2
  285. package/agent-docs/config/content.sections/callouts.md +2 -2
  286. package/agent-docs/config/content.sections/cookbooks.md +2 -2
  287. package/agent-docs/config/content.sections/frontmatter.md +2 -2
  288. package/agent-docs/config/content.sections/readerfilters.md +2 -2
  289. package/agent-docs/config/content.sections/related-reading.md +2 -2
  290. package/agent-docs/config/content.sections/relationships.md +2 -2
  291. package/agent-docs/config/content.sections/snippets.md +2 -2
  292. package/agent-docs/config/content.sections/templates.md +2 -2
  293. package/agent-docs/config/content.sections/variables.md +2 -2
  294. package/agent-docs/config/examples.md +22 -14
  295. package/agent-docs/config/examples.sections/feature-showcase.md +21 -13
  296. package/agent-docs/config/examples.sections/minimal-site.md +15 -10
  297. package/agent-docs/config/examples.sections/multilingual-help-center.md +15 -10
  298. package/agent-docs/config/examples.sections/parcel-api-documentation.md +15 -10
  299. package/agent-docs/config/examples.sections/related-reading.md +15 -10
  300. package/agent-docs/config/examples.sections/shared-company-preset.md +16 -11
  301. package/agent-docs/config/integrations.md +2 -2
  302. package/agent-docs/config/outputs.md +17 -13
  303. package/agent-docs/config/outputs.sections/exports.md +16 -13
  304. package/agent-docs/config/outputs.sections/metadata.md +3 -3
  305. package/agent-docs/config/outputs.sections/related-reading.md +3 -3
  306. package/agent-docs/config/publishing.md +2 -2
  307. package/agent-docs/config/publishing.sections/navigation.md +2 -2
  308. package/agent-docs/config/publishing.sections/redirects.md +2 -2
  309. package/agent-docs/config/publishing.sections/related-reading.md +2 -2
  310. package/agent-docs/config/site.md +2 -2
  311. package/agent-docs/config/site.sections/related-reading.md +2 -2
  312. package/agent-docs/config/site.sections/theme.md +2 -2
  313. package/agent-docs/config.md +2 -2
  314. package/agent-docs/configuration.md +22 -20
  315. package/agent-docs/configuration.sections/build-several-sites-from-shared-content.md +2 -2
  316. package/agent-docs/configuration.sections/change-inherited-lists-deliberately.md +5 -5
  317. package/agent-docs/configuration.sections/extract-a-section-with-include.md +4 -4
  318. package/agent-docs/configuration.sections/inspect-and-validate-changes.md +6 -6
  319. package/agent-docs/configuration.sections/related-reading.md +2 -2
  320. package/agent-docs/configuration.sections/separate-config-inheritance-from-page-metadata.md +2 -2
  321. package/agent-docs/configuration.sections/share-defaults-through-extends.md +7 -7
  322. package/agent-docs/configuration.sections/start-with-one-working-file.md +8 -6
  323. package/agent-docs/configuration.sections/understand-the-three-stages.md +2 -2
  324. package/agent-docs/configuration.sections/understand-where-paths-point.md +2 -2
  325. package/agent-docs/connect/mcp.md +1 -1
  326. package/agent-docs/content-delivery/agents.md +86 -0
  327. package/agent-docs/content-delivery/api.md +130 -0
  328. package/agent-docs/content-delivery/client.md +79 -0
  329. package/agent-docs/content-delivery/http-api/operations/get-content-representation-fa1d2e3f.md +394 -0
  330. package/agent-docs/content-delivery/http-api/operations/get-content-representation-head-4052375c.md +256 -0
  331. package/agent-docs/content-delivery/http-api/operations/get-content-resource-849f1c49.md +911 -0
  332. package/agent-docs/content-delivery/http-api/operations/get-content-resource-head-0a352acd.md +246 -0
  333. package/agent-docs/content-delivery/http-api/operations/list-content-resources-8e977ec7.md +913 -0
  334. package/agent-docs/content-delivery/http-api/operations/list-content-resources-head-b67cbad9.md +236 -0
  335. package/agent-docs/content-delivery/http-api.md +78 -0
  336. package/agent-docs/content-delivery/manifest.md +79 -0
  337. package/agent-docs/content-delivery/publish.md +72 -0
  338. package/agent-docs/content-delivery/render.md +73 -0
  339. package/agent-docs/content-delivery/rest.md +108 -0
  340. package/agent-docs/content-delivery/sections.md +110 -0
  341. package/agent-docs/content-delivery/select.md +100 -0
  342. package/agent-docs/content-delivery.md +79 -0
  343. package/agent-docs/contribute/agent-skills.md +1 -1
  344. package/agent-docs/cookbooks/authoring.md +7 -3
  345. package/agent-docs/cookbooks/site-workflows.md +8 -4
  346. package/agent-docs/cookbooks/welcome-email.md +7 -3
  347. package/agent-docs/documents.json +7707 -6283
  348. package/agent-docs/example-api/cedar/create-enrollment-7af3e5d2.md +2 -2
  349. package/agent-docs/example-api/cedar/get-legacy-parcel-6758d051.md +2 -2
  350. package/agent-docs/example-api/cedar/get-parcel-edee10e6.md +2 -2
  351. package/agent-docs/example-api/cedar/list-parcels-0345fb5f.md +2 -2
  352. package/agent-docs/example-api/cedar/parcel-delivered-7d1ba6db.md +2 -2
  353. package/agent-docs/example-api/cedar/upload-manifest-1af17891.md +2 -2
  354. package/agent-docs/example-api/cedar.md +2 -2
  355. package/agent-docs/example-api/create-note.md +2 -2
  356. package/agent-docs/example-api/generated/get-note-cbedb319.md +2 -2
  357. package/agent-docs/example-api/write-note.md +2 -2
  358. package/agent-docs/explore.md +2 -2
  359. package/agent-docs/glossary.md +3 -7
  360. package/agent-docs/ingredients/audit-site.md +2 -2
  361. package/agent-docs/ingredients/build-site.md +2 -2
  362. package/agent-docs/ingredients/compile-framework.md +2 -2
  363. package/agent-docs/ingredients/complete-page.md +2 -2
  364. package/agent-docs/ingredients/inspect-agent-bundle.md +2 -2
  365. package/agent-docs/ingredients/inspect-build.md +2 -2
  366. package/agent-docs/ingredients/preview-site.md +2 -2
  367. package/agent-docs/ingredients/refresh-agent-bundle.md +2 -2
  368. package/agent-docs/ingredients/scaffold-page.md +2 -2
  369. package/agent-docs/non-goals.md +2 -2
  370. package/agent-docs/provenance.json +4 -4
  371. package/agent-docs/publish/agent-discovery.md +1 -1
  372. package/agent-docs/publish/agent-friendliness.md +1 -1
  373. package/agent-docs/publish/agent-friendliness.sections/discover-a-page-with-a-small-context-budget.md +1 -1
  374. package/agent-docs/publish/agent-friendliness.sections/distinguish-examples-from-a-real-service.md +1 -1
  375. package/agent-docs/publish/agent-friendliness.sections/evidence-has-a-scope.md +1 -1
  376. package/agent-docs/publish/agent-friendliness.sections/keep-shared-instructions-complete.md +1 -1
  377. package/agent-docs/publish/agent-friendliness.sections/related-reading.md +1 -1
  378. package/agent-docs/publish/agent-friendliness.sections/secret-handshake.md +1 -1
  379. package/agent-docs/publish/agent-friendliness.sections/try-the-page-controls.md +1 -1
  380. package/agent-docs/publish/agent-friendliness.sections/use-the-transport-your-client-supports.md +1 -1
  381. package/agent-docs/publish/agent-friendliness.sections/verify-the-page-and-detect-changes.md +1 -1
  382. package/agent-docs/publish/agent-friendliness.sections/what-an-agent-reads.md +1 -1
  383. package/agent-docs/publish/agent-friendliness.sections/what-happens-to-an-unsupported-component.md +1 -1
  384. package/agent-docs/publish/api-references.md +10 -8
  385. package/agent-docs/publish/api-references.sections/author-the-reference-page.md +1 -1
  386. package/agent-docs/publish/api-references.sections/build-and-verify-the-output.md +1 -1
  387. package/agent-docs/publish/api-references.sections/inspect-the-machine-readable-contract.md +1 -1
  388. package/agent-docs/publish/api-references.sections/{generate-many-pages-selectively.md → next-steps.md} +28 -2
  389. package/agent-docs/publish/api-references.sections/preview-a-small-api-reference.md +1 -1
  390. package/agent-docs/publish/api-references.sections/put-the-spec-in-your-project.md +1 -1
  391. package/agent-docs/publish/api-references.sections/register-the-operation.md +1 -1
  392. package/agent-docs/publish/api-references.sections/related-reading.md +1 -1
  393. package/agent-docs/publish/api-references.sections/review-imported-content-before-publishing.md +1 -1
  394. package/agent-docs/publish/api-references.sections/what-readers-get.md +1 -1
  395. package/agent-docs/publish/audit.md +1 -1
  396. package/agent-docs/publish/audit.sections/add-project-tests.md +1 -1
  397. package/agent-docs/publish/audit.sections/check-agent-evaluation-reports.md +1 -1
  398. package/agent-docs/publish/audit.sections/check-before-pushing.md +1 -1
  399. package/agent-docs/publish/audit.sections/connect-a-documentation-test-suite.md +1 -1
  400. package/agent-docs/publish/audit.sections/read-the-report.md +1 -1
  401. package/agent-docs/publish/audit.sections/related-reading.md +1 -1
  402. package/agent-docs/publish/content-export.md +33 -17
  403. package/agent-docs/publish/content-export.sections/assets-downloads-and-notices.md +4 -4
  404. package/agent-docs/publish/content-export.sections/check-the-result.md +3 -3
  405. package/agent-docs/publish/content-export.sections/export-selected-pages.md +13 -10
  406. package/agent-docs/publish/content-export.sections/inspect-the-manifest.md +6 -4
  407. package/agent-docs/publish/content-export.sections/prerequisites.md +4 -4
  408. package/agent-docs/publish/content-export.sections/related-reading.md +3 -3
  409. package/agent-docs/publish/content-export.sections/review-exported-api-material.md +4 -4
  410. package/agent-docs/publish/content-export.sections/try-the-help-drawer-example.md +4 -4
  411. package/agent-docs/publish/content-export.sections/upgrade-an-existing-integration.md +34 -0
  412. package/agent-docs/publish/content-export.sections/what-the-representations-retain.md +5 -5
  413. package/agent-docs/publish/content-negotiation.md +2 -2
  414. package/agent-docs/publish/content-negotiation.sections/hosting-contract.md +2 -2
  415. package/agent-docs/publish/content-negotiation.sections/missing-pages.md +2 -2
  416. package/agent-docs/publish/content-negotiation.sections/related-reading.md +2 -2
  417. package/agent-docs/publish/content-negotiation.sections/validators-and-manifest-links.md +2 -2
  418. package/agent-docs/publish/content-negotiation.sections/verify-the-deployed-url.md +2 -2
  419. package/agent-docs/publish/content-negotiation.sections/what-if-the-host-cannot-negotiate.md +2 -2
  420. package/agent-docs/publish/content-negotiation.sections/what-shoalrun-builds-and-what-the-host-does.md +2 -2
  421. package/agent-docs/publish/content-negotiation.sections/why-this-matters.md +2 -2
  422. package/agent-docs/publish/deployment-check.md +2 -2
  423. package/agent-docs/publish/evals.md +1 -1
  424. package/agent-docs/publish/evals.sections/add-the-audit-hook.md +1 -1
  425. package/agent-docs/publish/evals.sections/check-the-report.md +1 -1
  426. package/agent-docs/publish/evals.sections/define-a-task-file.md +1 -1
  427. package/agent-docs/publish/evals.sections/diagnose-a-different-build.md +1 -1
  428. package/agent-docs/publish/evals.sections/prepare-a-report-for-the-built-site.md +1 -1
  429. package/agent-docs/publish/evals.sections/related-reading.md +1 -1
  430. package/agent-docs/publish/evals.sections/run-and-review-the-tasks.md +1 -1
  431. package/agent-docs/publish/evals.sections/shoalrun-s-own-example.md +1 -1
  432. package/agent-docs/publish/host-adapters.md +1 -1
  433. package/agent-docs/publish/manni.md +1 -1
  434. package/agent-docs/publish/manni.sections/check-the-result.md +1 -1
  435. package/agent-docs/publish/manni.sections/how-this-site-uses-manni.md +1 -1
  436. package/agent-docs/publish/manni.sections/optional-custom-policies.md +1 -1
  437. package/agent-docs/publish/manni.sections/prerequisites.md +1 -1
  438. package/agent-docs/publish/mcp-analytics.md +1 -1
  439. package/agent-docs/publish/mcp-analytics.sections/adapter-exports.md +1 -1
  440. package/agent-docs/publish/mcp-analytics.sections/enable-analytics.md +1 -1
  441. package/agent-docs/publish/mcp-analytics.sections/event-fields-and-service-mappings.md +1 -1
  442. package/agent-docs/publish/mcp-analytics.sections/optionally-collect-intent-and-group-calls.md +1 -1
  443. package/agent-docs/publish/mcp-analytics.sections/optionally-identify-the-client-and-model.md +1 -1
  444. package/agent-docs/publish/mcp-analytics.sections/related-reading.md +1 -1
  445. package/agent-docs/publish/mcp-analytics.sections/safeguards-and-limits.md +1 -1
  446. package/agent-docs/publish/mcp.md +12 -10
  447. package/agent-docs/publish/mcp.sections/check-budgets-and-errors.md +2 -2
  448. package/agent-docs/publish/mcp.sections/choose-the-documentation-source.md +7 -7
  449. package/agent-docs/publish/mcp.sections/configure-the-client.md +5 -5
  450. package/agent-docs/publish/mcp.sections/generate-a-vercel-endpoint.md +2 -2
  451. package/agent-docs/publish/mcp.sections/related-reading.md +4 -2
  452. package/agent-docs/publish/mcp.sections/search-then-read.md +2 -2
  453. package/agent-docs/publish/mcp.sections/serve-a-public-endpoint-on-node.md +2 -2
  454. package/agent-docs/publish/mcp.sections/verify-the-connection.md +2 -2
  455. package/agent-docs/publish/mcp.sections/why-offer-mcp-for-public-docs.md +2 -2
  456. package/agent-docs/publish/openapi-extension-mappings.md +2 -2
  457. package/agent-docs/publish/output.md +14 -14
  458. package/agent-docs/publish/output.sections/api-contracts.md +3 -3
  459. package/agent-docs/publish/output.sections/code-highlighting.md +3 -3
  460. package/agent-docs/publish/output.sections/current-limits.md +4 -4
  461. package/agent-docs/publish/output.sections/incremental-sync.md +3 -3
  462. package/agent-docs/publish/output.sections/manifest-records-and-sections.md +3 -3
  463. package/agent-docs/publish/output.sections/navigation-section-indexes.md +3 -3
  464. package/agent-docs/publish/output.sections/page-formats.md +3 -3
  465. package/agent-docs/publish/output.sections/published-output-contract.md +3 -3
  466. package/agent-docs/publish/output.sections/reader-appearance-and-controls.md +3 -3
  467. package/agent-docs/publish/output.sections/related-reading.md +3 -3
  468. package/agent-docs/publish/output.sections/response-identity.md +3 -3
  469. package/agent-docs/publish/output.sections/site-files.md +3 -3
  470. package/agent-docs/publish/output.sections/validate-an-existing-build-locally.md +5 -5
  471. package/agent-docs/publish/output.sections/where-files-go.md +11 -11
  472. package/agent-docs/publish/publications.md +1 -1
  473. package/agent-docs/publish/revisions.md +1 -1
  474. package/agent-docs/publish/seo.md +17 -3
  475. package/agent-docs/publish/seo.sections/related-reading.md +28 -0
  476. package/agent-docs/publish/seo.sections/set-the-public-address.md +36 -0
  477. package/agent-docs/publish/seo.sections/what-agents-receive.md +28 -0
  478. package/agent-docs/publish/seo.sections/what-the-build-adds.md +42 -0
  479. package/agent-docs/publish/seo.sections/write-the-page-title-and-summary.md +43 -0
  480. package/agent-docs/publish/single-source-sites.md +1 -1
  481. package/agent-docs/publish/troubleshooting.md +1 -1
  482. package/agent-docs/publish/vercel.md +1 -1
  483. package/agent-docs/publish/vercel.sections/check-the-deployment.md +1 -1
  484. package/agent-docs/publish/vercel.sections/include-an-mcp-endpoint.md +1 -1
  485. package/agent-docs/publish/vercel.sections/prepare-your-project.md +1 -1
  486. package/agent-docs/publish/vercel.sections/related-reading.md +1 -1
  487. package/agent-docs/publish.md +1 -1
  488. package/agent-docs/recipes/add-page.md +3 -3
  489. package/agent-docs/recipes/add-page.sections/audit-the-shoalrun-docs-project.md +2 -2
  490. package/agent-docs/recipes/add-page.sections/before-you-start.md +2 -3
  491. package/agent-docs/recipes/add-page.sections/build-the-shoalrun-docs-site.md +2 -2
  492. package/agent-docs/recipes/add-page.sections/check-agent-search-and-page-lookup.md +2 -2
  493. package/agent-docs/recipes/add-page.sections/check-the-built-page-artifacts.md +2 -2
  494. package/agent-docs/recipes/add-page.sections/check-the-outcome.md +2 -2
  495. package/agent-docs/recipes/add-page.sections/complete-the-guide-and-add-navigation.md +2 -2
  496. package/agent-docs/recipes/add-page.sections/install-the-site-dependencies.md +2 -2
  497. package/agent-docs/recipes/add-page.sections/regenerate-the-agent-documentation-bundle.md +3 -2
  498. package/agent-docs/recipes/add-page.sections/related-reading.md +2 -2
  499. package/agent-docs/recipes/add-page.sections/scaffold-a-new-guide.md +2 -2
  500. package/agent-docs/recipes/audit-docs.md +2 -3
  501. package/agent-docs/recipes/build-docs.md +2 -3
  502. package/agent-docs/recipes/preview-hybrid-search.md +2 -2
  503. package/agent-docs/recipes/preview-page.md +2 -3
  504. package/agent-docs/recipes/queue-email.md +2 -2
  505. package/agent-docs/recipes/refresh-agent-docs.md +21 -3
  506. package/agent-docs/recipes/send-welcome-email.md +2 -2
  507. package/agent-docs/reference/agent-skills.md +2 -2
  508. package/agent-docs/search-and-chat.md +1 -1
  509. package/agent-docs/search-index.json +1 -1
  510. package/agent-docs/start.md +7 -3
  511. package/agent-docs/start.sections/build-this-site.md +1 -1
  512. package/agent-docs/start.sections/migrating-from-github-packages.md +35 -0
  513. package/agent-docs/start.sections/prerequisites.md +1 -1
  514. package/agent-docs/start.sections/start-your-own-project.md +1 -1
  515. package/agent-docs/status.md +2 -2
  516. package/agent-docs/styling/color-modes.md +6 -2
  517. package/agent-docs/styling/footer.md +10 -8
  518. package/agent-docs/styling/header.md +5 -3
  519. package/agent-docs/styling/layouts.md +27 -5
  520. package/agent-docs/styling/layouts.sections/build-a-landing-page.md +7 -4
  521. package/agent-docs/styling/layouts.sections/build-a-splash-page.md +7 -4
  522. package/agent-docs/styling/layouts.sections/control-navigation-tabs.md +7 -4
  523. package/agent-docs/styling/layouts.sections/customize-the-hero.md +7 -4
  524. package/agent-docs/styling/layouts.sections/hero.md +8 -5
  525. package/agent-docs/styling/layouts.sections/hide-the-table-of-contents-or-give-content-more-room.md +54 -0
  526. package/agent-docs/styling/layouts.sections/html-markdown-and-agents.md +43 -0
  527. package/agent-docs/styling/layouts.sections/related-reading.md +7 -4
  528. package/agent-docs/styling/palettes.md +6 -2
  529. package/agent-docs/styling/share-images.md +6 -2
  530. package/agent-docs/styling/themes.md +6 -3
  531. package/agent-docs/styling/try.md +3 -15
  532. package/dist/api.js +70 -3
  533. package/dist/authoring-hints.d.ts +3 -0
  534. package/dist/authoring-hints.js +35 -0
  535. package/dist/authoring-project.d.ts +1 -1
  536. package/dist/authoring-project.js +2 -0
  537. package/dist/authoring-validation.js +2 -0
  538. package/dist/code-samples.js +22 -11
  539. package/dist/compiler-config.d.ts +1 -0
  540. package/dist/compiler-config.js +13 -0
  541. package/dist/compiler.js +2 -1
  542. package/dist/component-names.js +1 -1
  543. package/dist/component-transform.js +7 -1
  544. package/dist/content-delivery-contract.d.ts +108 -0
  545. package/dist/content-delivery-contract.js +15 -0
  546. package/dist/content-delivery-transport.d.ts +3 -0
  547. package/dist/content-delivery-transport.js +47 -0
  548. package/dist/content-delivery-validation.d.ts +7 -0
  549. package/dist/content-delivery-validation.js +122 -0
  550. package/dist/content-delivery.d.ts +21 -0
  551. package/dist/content-delivery.js +119 -0
  552. package/dist/content-export-anchors.d.ts +11 -0
  553. package/dist/content-export-anchors.js +79 -0
  554. package/dist/content-export-command.d.ts +4 -2
  555. package/dist/content-export-command.js +15 -2
  556. package/dist/content-export-comparison.d.ts +16 -0
  557. package/dist/content-export-comparison.js +48 -0
  558. package/dist/content-export-config.d.ts +17 -0
  559. package/dist/content-export-config.js +47 -3
  560. package/dist/content-export-render.js +20 -1
  561. package/dist/content-export.d.ts +5 -1
  562. package/dist/content-export.js +193 -40
  563. package/dist/content-mount.d.ts +11 -0
  564. package/dist/content-mount.js +73 -0
  565. package/dist/content-rest-client.d.ts +12 -0
  566. package/dist/content-rest-client.js +162 -0
  567. package/dist/content-rest-contract.d.ts +27 -0
  568. package/dist/content-rest-contract.js +9 -0
  569. package/dist/content-rest-server.d.ts +7 -0
  570. package/dist/content-rest-server.js +99 -0
  571. package/dist/content-source.d.ts +3 -1
  572. package/dist/frontmatter.js +8 -7
  573. package/dist/html-renderer.js +25 -0
  574. package/dist/markdown-sections.d.ts +2 -1
  575. package/dist/markdown-sections.js +8 -18
  576. package/dist/page-renderer.js +5 -3
  577. package/dist/publication-plan.js +2 -1
  578. package/dist/scaffold-placeholders.d.ts +2 -0
  579. package/dist/scaffold-placeholders.js +19 -0
  580. package/dist/section-identity.d.ts +24 -0
  581. package/dist/section-identity.js +137 -0
  582. package/examples/content-delivery/README.md +87 -0
  583. package/examples/content-delivery/app.js +91 -0
  584. package/examples/content-delivery/content/billing.mdx +22 -0
  585. package/examples/content-delivery/docs.config.yaml +36 -0
  586. package/examples/content-delivery/index.html +25 -0
  587. package/examples/content-delivery/preview.mjs +86 -0
  588. package/examples/content-delivery/snippets/refund-window.mdx +3 -0
  589. package/examples/help-drawer/README.md +2 -2
  590. package/examples/help-drawer/app.js +3 -3
  591. package/package.json +6 -3
  592. package/schemas/content-export.schema.json +469 -33
  593. package/schemas/content-rest.openapi.json +1627 -0
  594. package/skills/shoalrun-author/SKILL.md +2 -0
  595. package/styles/site.css +4 -1
  596. package/agent-docs/.well-known/shoalrun/navigation/changelog-tab-50f26fe22670.txt +0 -33
  597. package/agent-docs/publish/api-references.sections/add-useful-examples.md +0 -36
  598. package/agent-docs/publish/api-references.sections/describe-filters-that-do-not-use-their-openapi-parameter-name.md +0 -36
  599. package/agent-docs/publish/api-references.sections/link-guides-to-api-references.md +0 -36
  600. package/agent-docs/publish/api-references.sections/map-extension-values-to-shoalrun-status.md +0 -36
  601. package/agent-docs/publish/api-references.sections/publish-several-versions.md +0 -36
  602. package/agent-docs/publish/api-references.sections/use-a-template-for-editorial-context.md +0 -36
@@ -15,9 +15,9 @@ canonical: /styling/themes
15
15
 
16
16
  Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigation/docs-50f26fe22670.txt) (ID: docs). [All sections and pages](https://www.shoalrun.com/llms.min.txt)
17
17
 
18
- Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Customize > Themes
18
+ Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Themes
19
19
 
20
- **Updated: 2026-10-26.**
20
+ **Updated: 2026-10-27.**
21
21
 
22
22
  The `theme` setting controls how the HTML site looks. It has five keys, and each has a default:
23
23
 
@@ -96,7 +96,6 @@ Fonts set here become the `--font-body`, `--font-heading`, and `--font-code` [CS
96
96
  The HTML page links stylesheets in this order. Later files override earlier ones.
97
97
 
98
98
  1. `/assets/site.css`, which imports the base tokens and header styles.
99
- - `/assets/theme-preview.css` follows it, on pages that use the [theme previewer](https://www.shoalrun.com/styling/try.md).
100
99
  2. `/assets/theme.css`, for a preset other than `shoal`.
101
100
  3. `/assets/palette.css`, generated for any palette or mode other than `kelp` in light mode.
102
101
  4. `/assets/fonts.css`, generated from `theme.fonts`, unless it's `system` and sets nothing.
@@ -108,6 +107,10 @@ When a site uses a non-default preset, palette, or mode, the `html` element carr
108
107
  [data-theme="ledger"] .page-head h1 { letter-spacing: 0; }
109
108
  ```
110
109
 
110
+ ## HTML, Markdown, and agents
111
+
112
+ Presets and fonts style the HTML page through generated stylesheets. They do not change its Markdown text or add font and layout instructions to the Markdown twin. An agent reading Markdown receives the authored content without needing the theme assets. Keep labels, hierarchy, and instructions meaningful without relying on typography or position alone.
113
+
111
114
  ## Related reading
112
115
 
113
116
  ### Next steps
@@ -13,11 +13,11 @@ canonical: /styling/try
13
13
 
14
14
  > Documentation index: [llms.min.txt](https://www.shoalrun.com/llms.min.txt) · Document manifest: [documents.json](https://www.shoalrun.com/documents.json)
15
15
 
16
- Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigation/docs-50f26fe22670.txt) (ID: docs). [All sections and pages](https://www.shoalrun.com/llms.min.txt)
16
+ Navigation section: [Examples](https://www.shoalrun.com/.well-known/shoalrun/navigation/examples-tab-50f26fe22670.txt) (ID: examples-tab). [All sections and pages](https://www.shoalrun.com/llms.min.txt)
17
17
 
18
- Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Customize > Try a theme
18
+ Breadcrumbs: [Examples](https://www.shoalrun.com/config/examples.md) > Visual examples > Try a theme
19
19
 
20
- **Updated: 2026-10-26.**
20
+ **Updated: 2026-10-27.**
21
21
 
22
22
  Pick a shape, a palette, and a mode. This page restyles itself as you choose. Scroll down to see how each option styles the sample content, then copy the config into `docs.config.yaml`.
23
23
 
@@ -87,18 +87,6 @@ Readers always see the dark set.
87
87
 
88
88
  The site follows each reader's system setting, with an optional toggle.
89
89
 
90
- ## Add the previewer to a page
91
-
92
- Place the component on its own line in any MDX page:
93
-
94
- ```mdx
95
- <ThemePreview />
96
- ```
97
-
98
- The component takes no attributes. The build then publishes every preset and palette under `/assets/themes/`, so the previewer works on a static host. Sites that don't use the component don't publish those files.
99
-
100
- Without JavaScript, and in the Markdown twin, the component shows the preset and palette tables and an example config.
101
-
102
90
  ## Related reading
103
91
 
104
92
  ### Related topics
package/dist/api.js CHANGED
@@ -224,7 +224,7 @@ export class ApiReader {
224
224
  if (entries.length === 1 && /^[^?&#\s=]+$/.test(entries[0][0]) && ['string', 'number', 'boolean'].includes(typeof entries[0][1]))
225
225
  queryExpression = `${entries[0][0]}=${encodeURIComponent(String(entries[0][1]))}`;
226
226
  }
227
- if (location.startsWith('parameter:')) {
227
+ if (location.startsWith('parameter:') || location.startsWith('response-header:')) {
228
228
  const value = example.externalValue ? link(example.externalValue, 'Open external example') : inline(queryRule && location === `parameter:query:${queryRule.parameter}` ? queryExpression ?? JSON.stringify(example.value) : JSON.stringify(example.value));
229
229
  const sample = paragraph({ type: 'strong', children: [text(example.title)] }, text(': '), value, ...(example.description ? [text(` — ${example.description}`)] : []));
230
230
  sample.data = { hProperties: { className: ['api-parameter-example'] } };
@@ -465,8 +465,8 @@ export class ApiReader {
465
465
  blocks.push(heading(3, 'Responses'));
466
466
  for (const [status, initial] of Object.entries(op.responses ?? {})) {
467
467
  const { value: response, source: responseSource } = await this.deref(pathSource, initial);
468
- if (response.headers || response.links)
469
- throw new Error(`Response headers or links need an adapter: ${status}`);
468
+ if (response.links)
469
+ throw new Error(`Response links need an adapter: ${status}`);
470
470
  const description = String(response.description ?? '').trim();
471
471
  const mediaEntries = Object.entries(response.content ?? {});
472
472
  const responseBlocks = [];
@@ -474,6 +474,73 @@ export class ApiReader {
474
474
  responseBlocks.push({ type: 'docApiResponseHeader', data: { hName: 'div', hProperties: { className: ['api-response-header'] } }, children: [responseHeading, ...mediaEntries.map(([mediaType]) => ({ ...paragraph(inline(mediaType)), data: { hProperties: { className: ['api-response-media'] } } }))] });
475
475
  if (description)
476
476
  responseBlocks.push(...parsePlainMarkdown(description));
477
+ if (response.headers !== undefined && (!response.headers || typeof response.headers !== 'object' || Array.isArray(response.headers)))
478
+ throw new Error(`Response headers must be a mapping: ${status}`);
479
+ const headerNames = new Set();
480
+ const headers = [];
481
+ for (const [name, initialHeader] of Object.entries(response.headers ?? {})) {
482
+ // OpenAPI explicitly excludes Content-Type: response.content describes it.
483
+ if (name.toLowerCase() === 'content-type')
484
+ continue;
485
+ if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name))
486
+ throw new Error(`Invalid response header name: ${name}`);
487
+ if (headerNames.has(name.toLowerCase()))
488
+ throw new Error(`Duplicate response header name (case-insensitive): ${name}`);
489
+ headerNames.add(name.toLowerCase());
490
+ let header = initialHeader, headerSource = responseSource;
491
+ let overrideDescription;
492
+ const seen = new Set();
493
+ while (header?.$ref) {
494
+ if (typeof header.$ref !== 'string')
495
+ throw new Error(`Response header reference must be a string: ${name}`);
496
+ const allowed = schemaVersion === '3.1' ? ['$ref', 'description', 'summary'] : ['$ref'];
497
+ if (Object.keys(header).some(key => !allowed.includes(key)))
498
+ throw new Error(`Response header reference ${name} has unsupported siblings`);
499
+ for (const field of ['description', 'summary'])
500
+ if (header[field] !== undefined && typeof header[field] !== 'string')
501
+ throw new Error(`Invalid response header reference ${field}: ${name}`);
502
+ // Reference summary has no Header Object counterpart; OAS ignores it.
503
+ if (overrideDescription === undefined && header.description !== undefined)
504
+ overrideDescription = header.description;
505
+ const resolved = await this.ref(headerSource, header.$ref);
506
+ if (seen.has(resolved.identity))
507
+ throw new Error(`Recursive response header reference: ${name}`);
508
+ seen.add(resolved.identity);
509
+ header = resolved.value;
510
+ headerSource = resolved.source;
511
+ }
512
+ if (!header || typeof header !== 'object' || Array.isArray(header))
513
+ throw new Error(`Invalid response Header Object: ${name}`);
514
+ if (header.content !== undefined)
515
+ throw new Error(`Response header content needs an adapter: ${name}`);
516
+ const fields = new Set(['description', 'required', 'deprecated', 'schema', 'style', 'explode', 'example', 'examples']);
517
+ for (const field of Object.keys(header))
518
+ if (!fields.has(field) && !field.startsWith('x-'))
519
+ throw new Error(`Unsupported response header field ${field}: ${name}`);
520
+ for (const field of ['required', 'deprecated', 'explode'])
521
+ if (header[field] !== undefined && typeof header[field] !== 'boolean')
522
+ throw new Error(`Response header ${field} must be boolean: ${name}`);
523
+ if (header.description !== undefined && typeof header.description !== 'string')
524
+ throw new Error(`Response header description must be a string: ${name}`);
525
+ if (header.style !== undefined && header.style !== 'simple')
526
+ throw new Error(`Response header style must be simple: ${name}`);
527
+ if (header.schema === undefined)
528
+ throw new Error(`Response header requires a schema: ${name}`);
529
+ if (header.examples !== undefined && (!header.examples || typeof header.examples !== 'object' || Array.isArray(header.examples)))
530
+ throw new Error(`Response header examples must be a mapping: ${name}`);
531
+ const headerDescription = overrideDescription ?? header.description;
532
+ const detail = [heading(6, name), tagged(paragraph(text(header.required ? 'Required' : 'Optional')), 'api-parameter-presence', { 'data-required': header.required ? 'true' : 'false' })];
533
+ if (header.deprecated)
534
+ detail.push(tagged(paragraph(text('Deprecated response header.')), 'api-deprecated-note'));
535
+ if (headerDescription)
536
+ detail.push(...parsePlainMarkdown(headerDescription));
537
+ detail.push(paragraph(text(`Serialization: simple; explode: ${header.explode ?? false}.`)));
538
+ detail.push(...await this.schemaBlocks(headerSource, header.schema, schemaVersion, 6, new Set(), ['response', status, 'header', name], [], headerDescription));
539
+ await addExamples(headerSource, header, `response-header:${name}`, null, status, detail);
540
+ headers.push({ type: 'docApiParameter', data: { hName: 'section', hProperties: { className: ['api-parameter', 'api-response-header-field'] } }, children: detail });
541
+ }
542
+ if (headers.length)
543
+ responseBlocks.push(heading(5, 'Response headers'), ...headers);
477
544
  for (const [mediaType, media] of mediaEntries) {
478
545
  if (mediaEntries.length > 1)
479
546
  responseBlocks.push(tagged(heading(5, mediaType), 'api-media-heading'));
@@ -0,0 +1,3 @@
1
+ import type { ValidationFinding } from './authoring-findings.js';
2
+ /** Suggestions only: the author decides whether native relationships fit the links. */
3
+ export declare function authoringHints(body: string, file: string): ValidationFinding[];
@@ -0,0 +1,35 @@
1
+ import { parse } from './semantic-markdown.js';
2
+ const text = (node) => typeof node.value === 'string' ? node.value : (node.children ?? []).map(text).join('');
3
+ const contains = (node, predicate) => predicate(node) || (node.children ?? []).some((child) => contains(child, predicate));
4
+ /** Suggestions only: the author decides whether native relationships fit the links. */
5
+ export function authoringHints(body, file) {
6
+ let tree;
7
+ try {
8
+ tree = parse.parse(body);
9
+ }
10
+ catch {
11
+ return [];
12
+ } // Compilation reports syntax errors.
13
+ if (contains(tree, node => node.name === 'RelatedReading'))
14
+ return [];
15
+ const nodes = tree.children ?? [];
16
+ const definitions = new Map();
17
+ contains(tree, node => { if (node.type === 'definition')
18
+ definitions.set(node.identifier, node.url); return false; });
19
+ const documentLink = (node) => node.type === 'link' && node.url?.startsWith('doc:') || node.type === 'linkReference' && definitions.get(node.identifier)?.startsWith('doc:');
20
+ for (let index = 0; index < nodes.length; index++) {
21
+ const heading = nodes[index];
22
+ if (heading.type !== 'heading' || !/^related (reading|materials?)$/i.test(text(heading).trim()))
23
+ continue;
24
+ let end = index + 1;
25
+ while (end < nodes.length && !(nodes[end].type === 'heading' && nodes[end].depth <= heading.depth))
26
+ end++;
27
+ if (!nodes.slice(index + 1, end).some((node) => contains(node, documentLink)))
28
+ continue;
29
+ return [{ code: 'authoring.related-reading', severity: 'warning', file,
30
+ explanation: 'This page has a related-reading or related-material section with document links. Native relationships and RelatedReading may suit these connections.',
31
+ reference: 'guide.related-reading',
32
+ nextAction: 'Read guide.related-reading and guide.component.related-reading. Inspect the purpose and reason for each connection before choosing native relationships; keep manual links when they better fit the page.' }];
33
+ }
34
+ return [];
35
+ }
@@ -27,7 +27,7 @@ export declare const projectToolFailure: (error: unknown) => {
27
27
  schemaVersion: number;
28
28
  status: "error";
29
29
  error: {
30
- code: "invalid_input" | "internal_error" | "unknown_source" | "unsafe_path" | "invalid_project";
30
+ code: "invalid_input" | "internal_error" | "unsafe_path" | "unknown_source" | "invalid_project";
31
31
  message: string;
32
32
  };
33
33
  };
@@ -1,3 +1,4 @@
1
+ import { authoringHints } from './authoring-hints.js';
1
2
  import { createHash } from 'node:crypto';
2
3
  import { readFile, readdir, realpath } from 'node:fs/promises';
3
4
  import path from 'node:path';
@@ -121,6 +122,7 @@ export async function inspectAuthoringProject(configFile, options = {}) {
121
122
  publication: { channel: fm.channel ?? value.publications?.defaults?.channel, version: fm.version ?? value.publications?.defaults?.version, language: fm.language ?? defaultLanguage(value), ...(fm.publications ? { publications: fm.publications } : {}) },
122
123
  access: fm.access ?? null, aliases: [] });
123
124
  bodies.set(relative(file), doc.body);
125
+ findings.push(...authoringHints(doc.body, relative(file)).map(({ location, ...hint }) => hint));
124
126
  }
125
127
  catch (error) {
126
128
  findings.push({ code: 'project.invalid-page', severity: 'error', file: relative(file), explanation: error.message, nextAction: 'Repair the page metadata and inspect again.', reference: 'guide.frontmatter' });
@@ -1,3 +1,4 @@
1
+ import { authoringHints } from './authoring-hints.js';
1
2
  import { chmod, mkdir, mkdtemp, readFile, readdir, realpath, stat, writeFile } from 'node:fs/promises';
2
3
  import os from 'node:os';
3
4
  import path from 'node:path';
@@ -188,6 +189,7 @@ export async function validateAuthoringChangesWithHooks(configFile, options, hoo
188
189
  for (const file of affected) {
189
190
  try {
190
191
  const doc = await readDocument(path.join(shadow, file), loaded.value.frontmatter, undefined, capture.buffers.get(file).toString('utf8'));
192
+ report.findings.push(...authoringHints(doc.body, file));
191
193
  if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(doc.frontmatter.id))
192
194
  report.findings.push({ ...finding('validation.identity', 'Page IDs must begin with a letter/digit and contain only letters, digits, dots, underscores or hyphens.', 'Choose a stable ID and update its references.'), file, reference: 'guide.frontmatter-reference' });
193
195
  }
@@ -37,9 +37,10 @@ function resolve(sample) {
37
37
  headers.push(['Content-Type', sample.contentType]);
38
38
  return { headers, notes };
39
39
  }
40
+ const isHead = (sample) => sample.method.toUpperCase() === 'HEAD';
40
41
  const hasBody = (sample) => !!sample.body && !sample.body.formFields.length;
41
42
  function curl(sample) {
42
- const parts = [`curl --request ${sample.method.toUpperCase()}`, `--url ${shellQuote(sample.url)}`];
43
+ const parts = [isHead(sample) ? 'curl --head' : `curl --request ${sample.method.toUpperCase()}`, `--url ${shellQuote(sample.url)}`];
43
44
  for (const auth of sample.auth) {
44
45
  if (auth.kind === 'header')
45
46
  parts.push(`--header ${shellQuote(`${auth.name}: ${auth.value}`)}`);
@@ -76,7 +77,11 @@ function javascript(sample, node) {
76
77
  const lines = notes.map(note => `// ${note}`);
77
78
  if (node)
78
79
  lines.push('// Node.js 18 or newer provides a global fetch.');
79
- lines.push(`const response = await fetch(${JSON.stringify(sample.url)}, {`, options.join(',\n'), '});', '', 'const data = await response.json();', 'console.log(data);');
80
+ lines.push(`const response = await fetch(${JSON.stringify(sample.url)}, {`, options.join(',\n'), '});', '');
81
+ if (isHead(sample))
82
+ lines.push('console.log(response.status, Object.fromEntries(response.headers));');
83
+ else
84
+ lines.push('const body = await response.text();', "const mediaType = (response.headers.get('content-type') ?? '').split(';')[0].trim().toLowerCase();", "const data = body && (mediaType === 'application/json' || mediaType.endsWith('+json')) ? JSON.parse(body) : body;", 'console.log(data);');
80
85
  return lines.join('\n');
81
86
  }
82
87
  function python(sample) {
@@ -87,12 +92,16 @@ function python(sample) {
87
92
  if (hasBody(sample))
88
93
  lines.push(`data = ${JSON.stringify(sample.body.text)}`);
89
94
  const args = ['url', ...(headers.length ? ['headers=headers'] : []), ...(hasBody(sample) ? ['data=data'] : [])];
90
- lines.push('', `response = requests.${sample.method.toLowerCase()}(${args.join(', ')})`, 'print(response.json())');
95
+ lines.push('', `response = requests.${sample.method.toLowerCase()}(${args.join(', ')})`);
96
+ if (isHead(sample))
97
+ lines.push('print(response.status_code, dict(response.headers))');
98
+ else
99
+ lines.push('body = response.text', "media_type = response.headers.get('Content-Type', '').split(';')[0].strip().lower()", "data = response.json() if body and (media_type == 'application/json' or media_type.endswith('+json')) else body", 'print(data)');
91
100
  return lines.join('\n');
92
101
  }
93
102
  function go(sample) {
94
103
  const { headers, notes } = resolve(sample);
95
- const imports = ['"fmt"', '"io"', '"net/http"', ...(hasBody(sample) ? ['"strings"'] : [])].sort();
104
+ const imports = ['"fmt"', ...(isHead(sample) ? [] : ['"io"']), '"net/http"', ...(hasBody(sample) ? ['"strings"'] : [])].sort();
96
105
  const bodyVar = hasBody(sample) ? [`body := strings.NewReader(${goString(sample.body.text)})`, ''] : [];
97
106
  const bodyArg = hasBody(sample) ? 'body' : 'nil';
98
107
  const lines = [
@@ -103,8 +112,7 @@ function go(sample) {
103
112
  '\tif err != nil {', '\t\tpanic(err)', '\t}',
104
113
  ...headers.map(([name, value]) => `\treq.Header.Set(${JSON.stringify(name)}, ${JSON.stringify(value)})`),
105
114
  '\tres, err := http.DefaultClient.Do(req)', '\tif err != nil {', '\t\tpanic(err)', '\t}',
106
- '\tdefer res.Body.Close()', '\tdata, err := io.ReadAll(res.Body)', '\tif err != nil {', '\t\tpanic(err)', '\t}',
107
- '\tfmt.Println(string(data))', '}'
115
+ '\tdefer res.Body.Close()', ...(isHead(sample) ? ['\tfmt.Println(res.StatusCode, res.Header)'] : ['\tdata, err := io.ReadAll(res.Body)', '\tif err != nil {', '\t\tpanic(err)', '\t}', '\tfmt.Println(string(data))']), '}'
108
116
  ];
109
117
  return lines.join('\n');
110
118
  }
@@ -117,12 +125,14 @@ function java(sample) {
117
125
  'import java.net.URI;', 'import java.net.http.HttpClient;', 'import java.net.http.HttpRequest;', 'import java.net.http.HttpResponse;', '',
118
126
  'public class Main {', ' public static void main(String[] args) throws Exception {', ' HttpClient client = HttpClient.newHttpClient();',
119
127
  ' HttpRequest request = HttpRequest.newBuilder()', ` .uri(URI.create(${JSON.stringify(sample.url)}))`, ...builder, bodyMethod, ' .build();',
120
- ' HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());', ' System.out.println(response.body());', ' }', '}'
128
+ ' HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());', ...(isHead(sample) ? [' System.out.println(response.statusCode());', ' System.out.println(response.headers().map());'] : [' System.out.println(response.body());']), ' }', '}'
121
129
  ].join('\n');
122
130
  }
123
131
  function php(sample) {
124
132
  const { headers, notes } = resolve(sample);
125
133
  const array = [' CURLOPT_URL => ' + phpString(sample.url), ` CURLOPT_CUSTOMREQUEST => ${phpString(sample.method.toUpperCase())}`, ' CURLOPT_RETURNTRANSFER => true'];
134
+ if (isHead(sample))
135
+ array.push(' CURLOPT_NOBODY => true', ' CURLOPT_HEADER => true');
126
136
  if (headers.length)
127
137
  array.push(` CURLOPT_HTTPHEADER => [\n${headers.map(([name, value]) => ` ${phpString(`${name}: ${value}`)}`).join(',\n')}\n ]`);
128
138
  if (hasBody(sample))
@@ -136,15 +146,16 @@ function php(sample) {
136
146
  }
137
147
  function ruby(sample) {
138
148
  const { headers, notes } = resolve(sample);
139
- const klass = sample.method.toLowerCase() === 'get' ? 'Get' : sample.method[0].toUpperCase() + sample.method.slice(1);
149
+ const method = sample.method.toLowerCase();
150
+ const klass = method[0].toUpperCase() + method.slice(1);
140
151
  const lines = [
141
152
  ...notes.map(note => `# ${note}`),
142
153
  "require 'net/http'", "require 'uri'", '',
143
- `uri = URI(${rubyString(sample.url)})`, 'http = Net::HTTP.new(uri.host, uri.port)', 'http.use_ssl = true', '',
154
+ `uri = URI(${rubyString(sample.url)})`, 'http = Net::HTTP.new(uri.host, uri.port)', 'http.use_ssl = uri.scheme == \'https\'', '',
144
155
  `request = Net::HTTP::${klass}.new(uri)`,
145
156
  ...headers.map(([name, value]) => `request[${rubyString(name)}] = ${rubyString(value)}`),
146
157
  ...(hasBody(sample) ? [`request.body = ${rubyString(sample.body.text)}`] : []),
147
- '', 'response = http.request(request)', 'puts response.body'
158
+ '', 'response = http.request(request)', ...(isHead(sample) ? ['puts response.code', 'puts response.to_hash'] : ['puts response.body'])
148
159
  ];
149
160
  return lines.join('\n');
150
161
  }
@@ -159,7 +170,7 @@ function csharp(sample) {
159
170
  ` var request = new HttpRequestMessage(new HttpMethod(${JSON.stringify(sample.method.toUpperCase())}), ${JSON.stringify(sample.url)});`,
160
171
  ...contentHeaders.map(([name, value]) => ` request.Headers.TryAddWithoutValidation(${JSON.stringify(name)}, ${JSON.stringify(value)});`),
161
172
  ...(hasBody(sample) ? [` request.Content = new StringContent(${csharpString(sample.body.text)}, Encoding.UTF8, ${JSON.stringify(contentType)});`] : []),
162
- ' var response = await client.SendAsync(request);', ' Console.WriteLine(await response.Content.ReadAsStringAsync());', ' }', '}'
173
+ ' var response = await client.SendAsync(request);', ...(isHead(sample) ? [' Console.WriteLine((int)response.StatusCode);', ' Console.WriteLine(response.Headers);', ' Console.WriteLine(response.Content.Headers);'] : [' Console.WriteLine(await response.Content.ReadAsStringAsync());']), ' }', '}'
163
174
  ].join('\n');
164
175
  }
165
176
  // cURL comes first: the Markdown twin and agent bundle keep only that one.
@@ -58,6 +58,7 @@ export declare function configField(value: unknown, key: string): unknown;
58
58
  export declare function resolvedCompilerConfig(value: unknown): ResolvedCompilerConfig;
59
59
  /** A section-level mapping guard for validators that accept arbitrary YAML. */
60
60
  export declare function configMappingAt(value: unknown, setting: string): ConfigMapping;
61
+ export declare function navigationHeading(outputs: unknown): string | false;
61
62
  export declare function navigationCounts(outputs: unknown): boolean;
62
63
  /**
63
64
  * Apply the compiler's existing required-section checks at their original
@@ -18,6 +18,19 @@ export function configMappingAt(value, setting) {
18
18
  throw new Error(`${setting} must be a mapping`);
19
19
  return value;
20
20
  }
21
+ export function navigationHeading(outputs) {
22
+ const navigation = configField(configField(outputs, 'html'), 'navigation');
23
+ if (navigation === undefined)
24
+ return 'Explore';
25
+ const heading = configMappingAt(navigation, 'outputs.html.navigation').heading;
26
+ if (heading === undefined)
27
+ return 'Explore';
28
+ if (heading === false)
29
+ return false;
30
+ if (typeof heading !== 'string' || !heading.trim())
31
+ throw new Error('outputs.html.navigation.heading must be nonempty text or false');
32
+ return heading.trim();
33
+ }
21
34
  export function navigationCounts(outputs) {
22
35
  const navigation = configField(configField(outputs, 'html'), 'navigation');
23
36
  if (navigation === undefined)
package/dist/compiler.js CHANGED
@@ -7,7 +7,7 @@ import { resolveTaxonomy } from './taxonomy.js';
7
7
  import { resolveMcp } from './mcp-config.js';
8
8
  import { fictionalDocument, resolveLlmsDiscovery } from './llms-discovery.js';
9
9
  import { resolveAnalytics } from './analytics.js';
10
- import { navigationCounts } from './compiler-config.js';
10
+ import { navigationCounts, navigationHeading } from './compiler-config.js';
11
11
  import { validateAuthoringGuidance } from './authoring-guidance.js';
12
12
  import { loadFreshness } from './freshness.js';
13
13
  import { resolveAgentDiscovery } from './agent-discovery.js';
@@ -226,6 +226,7 @@ export async function compile(configFile, destination, provenance = {}, options
226
226
  // `demo` ships it hidden until a page is opened with ?theme-switcher.
227
227
  const themeSwitcherSetting = configField(htmlOptions, 'themeSwitcher') ?? false;
228
228
  navigationCounts(config.outputs);
229
+ navigationHeading(config.outputs);
229
230
  if (typeof themeSwitcherSetting !== 'boolean' && themeSwitcherSetting !== 'demo')
230
231
  throw new Error('outputs.html.themeSwitcher must be true, false, or demo');
231
232
  const themeSwitcher = themeSwitcherSetting !== false;
@@ -1 +1 @@
1
- export const builtinComponentNames = new Set('FrontmatterReference ForPublication ReaderSection ReaderChoice ReaderFilter Only Badge Kbd Tooltip InfoHint Progress Math ActionLink Button DefinitionList Term Definition Steps Timeline Milestone FileTree Tree Folder File Table CollapsibleGroup Collapsible Section Hero ThemePreview Diagram Image Tabs Walkthrough Step Tab Fields Field CookbookChooser DocCard DocCards DocCollection RelatedReading ApiExample ApiSchema Snippet Var DocLink Callout'.split(' '));
1
+ export const builtinComponentNames = new Set('Anchor FrontmatterReference ForPublication ReaderSection ReaderChoice ReaderFilter Only Badge Kbd Tooltip InfoHint Progress Math ActionLink Button DefinitionList Term Definition Steps Timeline Milestone FileTree Tree Folder File Table CollapsibleGroup Collapsible Section Hero ThemePreview Diagram Image Tabs Walkthrough Step Tab Fields Field CookbookChooser DocCard DocCards DocCollection RelatedReading ApiExample ApiSchema Snippet Var DocLink Callout'.split(' '));
@@ -15,6 +15,7 @@ import { validateReaderFilterControl, validateReaderSelection } from './reader-f
15
15
  import { walkthroughComponent } from './walkthrough.js';
16
16
  import { procedureComponent } from './procedure-components.js';
17
17
  import { parsePlainMarkdown, paragraph, link, text } from './semantic-markdown.js';
18
+ import { lowerSectionMarkers, sectionIdentities } from './section-identity.js';
18
19
  function isMdxRoot(tree) {
19
20
  return !!tree && typeof tree === 'object'
20
21
  && tree.type === 'root'
@@ -58,6 +59,7 @@ function literalAttributes(attributes) {
58
59
  export function transformMdx(tree, current, registry, snippets = new Map(), projectValues = {}, uses = [], calloutTypes = resolveCalloutTypes(undefined, current.file), projectRoot, readerConfig, frontmatterConfig = {}, publicationConfig, badgeVariants = resolveBadgeVariants(undefined, current.file), componentPlugins = new Map()) {
59
60
  if (!isMdxRoot(tree))
60
61
  throw new Error(`${current.file}: parsed content must be a root with children`);
62
+ tree = lowerSectionMarkers(tree, current.file);
61
63
  let pluginDepth = 0;
62
64
  let tabsIndex = 0;
63
65
  let walkthroughIndex = 0;
@@ -98,6 +100,8 @@ export function transformMdx(tree, current, registry, snippets = new Map(), proj
98
100
  if (node.type === 'heading' && stack.length)
99
101
  throw new Error(`${sourceFile}: snippet headings need an anchor adapter; put headings in the page`);
100
102
  if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
103
+ if (node.name === 'Anchor')
104
+ throw new Error(`${sourceFile}: <Anchor> must be the single trailing marker of an authored root level-two heading`);
101
105
  if (node.name && componentPlugins.has(node.name)) {
102
106
  const start = node.position?.start;
103
107
  const location = `${sourceFile}${start ? `:${start.line}:${start.column}` : ''}: <${node.name}>`;
@@ -693,5 +697,7 @@ export function transformMdx(tree, current, registry, snippets = new Map(), proj
693
697
  }
694
698
  return node;
695
699
  }
696
- return walk(tree, {}, [], current.file);
700
+ const transformed = walk(tree, {}, [], current.file);
701
+ sectionIdentities(transformed, current.file);
702
+ return transformed;
697
703
  }
@@ -0,0 +1,108 @@
1
+ /** Browser-safe delivery contracts. These types do not import the compiler. */
2
+ export type ContentPublication = {
3
+ channel: string;
4
+ version: string;
5
+ language: string;
6
+ };
7
+ export type ContentFormat = 'html' | 'markdown';
8
+ export type ContentRef = {
9
+ kind: 'page';
10
+ documentId: string;
11
+ } | {
12
+ kind: 'section';
13
+ documentId: string;
14
+ sectionId: string;
15
+ } | {
16
+ kind: 'snippet';
17
+ id: string;
18
+ };
19
+ export type ContentFile = {
20
+ path: string;
21
+ bytes: number;
22
+ digest: string;
23
+ };
24
+ export type ContentAsset = ContentFile & {
25
+ mediaType: string;
26
+ };
27
+ export type ContentAnchor = {
28
+ id: string;
29
+ exportedId: string;
30
+ title?: string;
31
+ };
32
+ export type ContentLink = {
33
+ key: string;
34
+ kind: 'resource' | 'canonical' | 'external' | 'asset';
35
+ href: string;
36
+ ref?: ContentRef;
37
+ fragment?: string;
38
+ query?: string;
39
+ asset?: string;
40
+ };
41
+ export type ContentRepresentation = ContentAsset & {
42
+ anchors: ContentAnchor[];
43
+ links: ContentLink[];
44
+ };
45
+ export type ContentResource = {
46
+ ref: ContentRef;
47
+ publication: ContentPublication;
48
+ title: string;
49
+ summary: string;
50
+ type: string;
51
+ canonicalUrl?: string;
52
+ source?: {
53
+ documentId?: string;
54
+ snippetId?: string;
55
+ valuesDigest?: string;
56
+ };
57
+ representations: Partial<Record<ContentFormat, ContentRepresentation>>;
58
+ assets: string[];
59
+ externalDependencies: Array<{
60
+ url: string;
61
+ kind: 'image';
62
+ }>;
63
+ };
64
+ export type ContentManifest = {
65
+ schemaVersion: 1;
66
+ kind: 'shoalrun-content-export';
67
+ digest: string;
68
+ publicBase: string;
69
+ publication: ContentPublication;
70
+ review: {
71
+ status: 'ok' | 'required';
72
+ apis: Array<{
73
+ apiId: string;
74
+ digest: string;
75
+ }>;
76
+ };
77
+ resources: ContentResource[];
78
+ assets: ContentAsset[];
79
+ files: ContentFile[];
80
+ diagnostics: Array<{
81
+ code: string;
82
+ documentId?: string;
83
+ message: string;
84
+ }>;
85
+ };
86
+ export type ContentResult = {
87
+ resource: Readonly<ContentResource>;
88
+ representation: Readonly<ContentRepresentation>;
89
+ format: ContentFormat;
90
+ content: string;
91
+ revision: string;
92
+ };
93
+ export interface ContentSnapshot {
94
+ readonly revision: string;
95
+ readonly publication: Readonly<ContentPublication>;
96
+ list(): readonly Readonly<ContentResource>[];
97
+ get(ref: ContentRef, options: {
98
+ format: ContentFormat;
99
+ signal?: AbortSignal;
100
+ }): Promise<ContentResult>;
101
+ dispose(): void;
102
+ }
103
+ export type ContentErrorCode = 'invalid_manifest' | 'not_found' | 'unsupported_format' | 'stale_revision' | 'network_error' | 'invalid_content' | 'disposed';
104
+ export declare class ContentDeliveryError extends Error {
105
+ readonly code: ContentErrorCode;
106
+ constructor(code: ContentErrorCode, message: string);
107
+ }
108
+ export declare function contentRefKey(ref: ContentRef): string;
@@ -0,0 +1,15 @@
1
+ export class ContentDeliveryError extends Error {
2
+ code;
3
+ constructor(code, message) {
4
+ super(message);
5
+ this.code = code;
6
+ this.name = 'ContentDeliveryError';
7
+ }
8
+ }
9
+ export function contentRefKey(ref) {
10
+ switch (ref.kind) {
11
+ case 'page': return JSON.stringify(['page', ref.documentId]);
12
+ case 'section': return JSON.stringify(['section', ref.documentId, ref.sectionId]);
13
+ case 'snippet': return JSON.stringify(['snippet', ref.id]);
14
+ }
15
+ }
@@ -0,0 +1,3 @@
1
+ export declare function freeze<T>(value: T): T;
2
+ export declare function sha256(bytes: Uint8Array): Promise<string>;
3
+ export declare function readBounded(response: Response, limit: number, signal: AbortSignal): Promise<Uint8Array>;
@@ -0,0 +1,47 @@
1
+ import { ContentDeliveryError } from './content-delivery-contract.js';
2
+ export function freeze(value) { if (value && typeof value === 'object') {
3
+ Object.freeze(value);
4
+ for (const child of Object.values(value))
5
+ freeze(child);
6
+ } return value; }
7
+ export async function sha256(bytes) { return [...new Uint8Array(await globalThis.crypto.subtle.digest('SHA-256', bytes))].map(byte => byte.toString(16).padStart(2, '0')).join(''); }
8
+ export async function readBounded(response, limit, signal) {
9
+ const declared = response.headers.get('content-length');
10
+ if (declared && (!/^\d+$/.test(declared) || Number(declared) > limit)) {
11
+ await response.body?.cancel().catch(() => { });
12
+ throw new ContentDeliveryError('invalid_content', 'Response exceeds the content size limit.');
13
+ }
14
+ const reader = response.body?.getReader();
15
+ if (!reader)
16
+ return new Uint8Array();
17
+ const abort = () => { void reader.cancel(signal.reason).catch(() => { }); };
18
+ signal.addEventListener('abort', abort, { once: true });
19
+ const chunks = [];
20
+ let size = 0;
21
+ try {
22
+ while (true) {
23
+ signal.throwIfAborted();
24
+ const next = await reader.read();
25
+ signal.throwIfAborted();
26
+ if (next.done)
27
+ break;
28
+ size += next.value.byteLength;
29
+ if (size > limit) {
30
+ await reader.cancel();
31
+ throw new ContentDeliveryError('invalid_content', 'Response exceeds the content size limit.');
32
+ }
33
+ chunks.push(next.value);
34
+ }
35
+ }
36
+ finally {
37
+ signal.removeEventListener('abort', abort);
38
+ reader.releaseLock();
39
+ }
40
+ const bytes = new Uint8Array(size);
41
+ let offset = 0;
42
+ for (const chunk of chunks) {
43
+ bytes.set(chunk, offset);
44
+ offset += chunk.length;
45
+ }
46
+ return bytes;
47
+ }
@@ -0,0 +1,7 @@
1
+ import type { ContentManifest, ContentRef } from './content-delivery-contract.js';
2
+ export declare const safeContentPath: (value: any) => value is string;
3
+ export declare const validContentPublication: (value: any) => boolean;
4
+ export declare function validContentRef(value: any): value is ContentRef;
5
+ export declare function validateContentManifest(value: any, maxResources?: number, maxResourceBytes?: number): asserts value is ContentManifest;
6
+ /** Shared metadata validation; transport supplies its file/asset inventory policy. */
7
+ export declare function validateContentResources(resources: any[], expectedPublication: unknown, assets: Set<string>, checkRepresentation: (value: any) => boolean, publicBase?: string): void;