@shoalrun/cli 0.1.0-alpha.16 → 0.1.0-alpha.18

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 (703) hide show
  1. package/AUTHORING.md +29 -0
  2. package/CHANGELOG.md +40 -0
  3. package/DEPLOYMENT-PROFILES.md +96 -5
  4. package/README.md +59 -3
  5. package/agent-docs/.well-known/shoalrun/navigation/project-updates-50f26fe22670.txt +21 -17
  6. package/agent-docs/SNAPSHOT.json +5 -5
  7. package/agent-docs/api-docs/focused-contracts.md +4 -4
  8. package/agent-docs/api-docs/generate.md +11 -11
  9. package/agent-docs/api-docs/generate.sections/add-useful-examples.md +3 -3
  10. package/agent-docs/api-docs/generate.sections/choose-generated-references-or-mdx.md +4 -4
  11. package/agent-docs/api-docs/generate.sections/describe-filters-that-do-not-use-their-openapi-parameter-name.md +1 -1
  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 +1 -1
  14. package/agent-docs/api-docs/generate.sections/map-extension-values-to-shoalrun-status.md +1 -1
  15. package/agent-docs/api-docs/generate.sections/override-generated-reference-order-in-navigation.md +4 -4
  16. package/agent-docs/api-docs/generate.sections/related-reading.md +1 -1
  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 +7 -7
  19. package/agent-docs/author/add-page.md +3 -3
  20. package/agent-docs/author/agent-overview.md +3 -3
  21. package/agent-docs/author/agent-workflow.md +7 -7
  22. package/agent-docs/author/analytics.md +27 -27
  23. package/agent-docs/author/analytics.sections/adapter-exports-and-consent.md +3 -3
  24. package/agent-docs/author/analytics.sections/built-in-events.md +15 -15
  25. package/agent-docs/author/analytics.sections/configure-an-adapter.md +1 -1
  26. package/agent-docs/author/analytics.sections/custom-interactions.md +2 -2
  27. package/agent-docs/author/analytics.sections/event-format.md +2 -2
  28. package/agent-docs/author/analytics.sections/html-markdown-and-agents.md +4 -4
  29. package/agent-docs/author/analytics.sections/inspect-events-locally.md +2 -2
  30. package/agent-docs/author/analytics.sections/map-events-to-your-service.md +3 -3
  31. package/agent-docs/author/analytics.sections/posthog-example.md +3 -3
  32. package/agent-docs/author/analytics.sections/related-reading.md +1 -1
  33. package/agent-docs/author/authoring-agent.md +3 -3
  34. package/agent-docs/author/coding-agent.md +4 -4
  35. package/agent-docs/author/components/api-embeds.md +6 -6
  36. package/agent-docs/author/components/api-embeds.sections/apiexample.md +3 -3
  37. package/agent-docs/author/components/api-embeds.sections/html-markdown-and-agents.md +1 -1
  38. package/agent-docs/author/components/api-embeds.sections/related-reading.md +1 -1
  39. package/agent-docs/author/components/badge.md +2 -2
  40. package/agent-docs/author/components/callout.md +2 -2
  41. package/agent-docs/author/components/cards.md +16 -16
  42. package/agent-docs/author/components/cards.sections/add-a-lucide-icon.md +4 -4
  43. package/agent-docs/author/components/cards.sections/build-a-collection.md +7 -7
  44. package/agent-docs/author/components/cards.sections/curate-a-reading-list.md +9 -9
  45. package/agent-docs/author/components/cards.sections/html-markdown-and-agents.md +3 -3
  46. package/agent-docs/author/components/cards.sections/link-to-one-document.md +3 -3
  47. package/agent-docs/author/components/cards.sections/override-card-text.md +5 -5
  48. package/agent-docs/author/components/cards.sections/related-reading.md +3 -3
  49. package/agent-docs/author/components/code-blocks.md +2 -2
  50. package/agent-docs/author/components/collapsible.md +3 -3
  51. package/agent-docs/author/components/cookbook-chooser.md +5 -5
  52. package/agent-docs/author/components/custom/react.md +8 -8
  53. package/agent-docs/author/components/custom/react.sections/html-markdown-and-agents.md +3 -3
  54. package/agent-docs/author/components/custom/react.sections/interactive-react-example.md +2 -2
  55. package/agent-docs/author/components/custom/react.sections/registration.md +1 -1
  56. package/agent-docs/author/components/custom/react.sections/related-reading.md +1 -1
  57. package/agent-docs/author/components/custom/react.sections/share-the-model-with-the-browser.md +3 -3
  58. package/agent-docs/author/components/custom/react.sections/where-the-content-lives.md +3 -3
  59. package/agent-docs/author/components/custom.md +7 -7
  60. package/agent-docs/author/components/definition-list.md +2 -2
  61. package/agent-docs/author/components/diagrams/d2-gallery.md +2 -2
  62. package/agent-docs/author/components/diagrams/d2-gallery.sections/basic-shapes.md +2 -2
  63. package/agent-docs/author/components/diagrams/d2-gallery.sections/flows-and-structures.md +2 -2
  64. package/agent-docs/author/components/diagrams/d2-gallery.sections/html-markdown-and-agents.md +2 -2
  65. package/agent-docs/author/components/diagrams/d2-gallery.sections/layout-engines.md +2 -2
  66. package/agent-docs/author/components/diagrams/d2-gallery.sections/related-reading.md +2 -2
  67. package/agent-docs/author/components/diagrams/d2-gallery.sections/sequences-and-grids.md +2 -2
  68. package/agent-docs/author/components/diagrams/d2-gallery.sections/styles-and-code.md +2 -2
  69. package/agent-docs/author/components/diagrams/pele-gallery.md +3 -3
  70. package/agent-docs/author/components/diagrams/pele-gallery.sections/charts-and-planning.md +2 -2
  71. package/agent-docs/author/components/diagrams/pele-gallery.sections/flowchart-shapes.md +2 -2
  72. package/agent-docs/author/components/diagrams/pele-gallery.sections/flows-and-behavior.md +2 -2
  73. package/agent-docs/author/components/diagrams/pele-gallery.sections/html-markdown-and-agents.md +3 -3
  74. package/agent-docs/author/components/diagrams/pele-gallery.sections/related-reading.md +2 -2
  75. package/agent-docs/author/components/diagrams/pele-gallery.sections/specialized-diagrams.md +2 -2
  76. package/agent-docs/author/components/diagrams/pele-gallery.sections/systems-and-structures.md +2 -2
  77. package/agent-docs/author/components/diagrams.md +8 -8
  78. package/agent-docs/author/components/doc-link.md +3 -3
  79. package/agent-docs/author/components/fields.md +18 -18
  80. package/agent-docs/author/components/file-tree.md +2 -2
  81. package/agent-docs/author/components/images.md +5 -5
  82. package/agent-docs/author/components/info-hint.md +3 -3
  83. package/agent-docs/author/components/kbd.md +2 -2
  84. package/agent-docs/author/components/math.md +2 -2
  85. package/agent-docs/author/components/only.md +3 -3
  86. package/agent-docs/author/components/progress.md +3 -3
  87. package/agent-docs/author/components/steps.md +2 -2
  88. package/agent-docs/author/components/tables.md +2 -2
  89. package/agent-docs/author/components/tabs.md +5 -5
  90. package/agent-docs/author/components/timeline.md +2 -2
  91. package/agent-docs/author/components/tooltips.md +2 -2
  92. package/agent-docs/author/components/walkthroughs.md +2 -2
  93. package/agent-docs/author/components/walkthroughs.sections/attributes.md +1 -1
  94. package/agent-docs/author/components/walkthroughs.sections/build-up-code.md +1 -1
  95. package/agent-docs/author/components/walkthroughs.sections/choose-a-layout.md +2 -2
  96. package/agent-docs/author/components/walkthroughs.sections/explain-one-file.md +1 -1
  97. package/agent-docs/author/components/walkthroughs.sections/html-markdown-and-agents.md +1 -1
  98. package/agent-docs/author/components/walkthroughs.sections/related-reading.md +1 -1
  99. package/agent-docs/author/components/walkthroughs.sections/syntax.md +1 -1
  100. package/agent-docs/author/components/walkthroughs.sections/take-code-from-a-file.md +1 -1
  101. package/agent-docs/author/components.md +2 -2
  102. package/agent-docs/author/content.md +3 -3
  103. package/agent-docs/author/cookbooks.md +9 -9
  104. package/agent-docs/author/css.md +4 -4
  105. package/agent-docs/author/css.sections/borders-fields-and-navigation-tokens.md +3 -3
  106. package/agent-docs/author/css.sections/core-color-tokens.md +3 -3
  107. package/agent-docs/author/css.sections/html-markdown-and-agents.md +4 -4
  108. package/agent-docs/author/css.sections/page-attributes.md +3 -3
  109. package/agent-docs/author/css.sections/page-transitions.md +3 -3
  110. package/agent-docs/author/css.sections/responsive-behavior.md +3 -3
  111. package/agent-docs/author/css.sections/status-code-and-callout-tokens.md +3 -3
  112. package/agent-docs/author/css.sections/typography-shape-and-width-tokens.md +3 -3
  113. package/agent-docs/author/custom-metadata.md +13 -13
  114. package/agent-docs/author/custom-metadata.sections/add-a-custom-page-field.md +4 -4
  115. package/agent-docs/author/custom-metadata.sections/choose-text-for-each-surface.md +3 -3
  116. package/agent-docs/author/custom-metadata.sections/preview-changes-to-metadata-providers.md +2 -2
  117. package/agent-docs/author/custom-metadata.sections/read-metadata-from-a-project-module.md +3 -3
  118. package/agent-docs/author/custom-metadata.sections/related-reading.md +1 -1
  119. package/agent-docs/author/design-templates.md +3 -3
  120. package/agent-docs/author/design-writing-guides.md +3 -3
  121. package/agent-docs/author/frontmatter-reference.md +59 -16
  122. package/agent-docs/author/frontmatter-reference.sections/categorize-connect-and-present-the-page.md +64 -0
  123. package/agent-docs/author/frontmatter-reference.sections/choose-a-publication-and-visibility.md +14 -12
  124. package/agent-docs/author/frontmatter-reference.sections/control-output-details.md +2 -2
  125. package/agent-docs/author/frontmatter-reference.sections/feature-availability.md +59 -0
  126. package/agent-docs/author/frontmatter-reference.sections/global-defaults-and-enforced-values.md +2 -2
  127. package/agent-docs/author/frontmatter-reference.sections/html-markdown-and-agents.md +3 -3
  128. package/agent-docs/author/frontmatter-reference.sections/identify-and-route-a-page.md +2 -2
  129. package/agent-docs/author/frontmatter-reference.sections/point-agents-to-it.md +2 -2
  130. package/agent-docs/author/frontmatter-reference.sections/product-publication-fields.md +37 -0
  131. package/agent-docs/author/frontmatter-reference.sections/project-defined-fields.md +2 -2
  132. package/agent-docs/author/frontmatter-reference.sections/related-reading.md +2 -2
  133. package/agent-docs/author/frontmatter-reference.sections/use-the-local-files-while-authoring.md +4 -4
  134. package/agent-docs/author/frontmatter-reference.sections/when-the-files-update.md +2 -2
  135. package/agent-docs/author/frontmatter.md +13 -13
  136. package/agent-docs/author/frontmatter.sections/audience-badges.md +3 -3
  137. package/agent-docs/author/frontmatter.sections/give-deprecation-guidance.md +4 -4
  138. package/agent-docs/author/frontmatter.sections/global-defaults-and-enforced-values.md +1 -1
  139. package/agent-docs/author/frontmatter.sections/optional-native-fields.md +4 -4
  140. package/agent-docs/author/frontmatter.sections/publication-fields.md +2 -2
  141. package/agent-docs/author/frontmatter.sections/publishing-policy.md +1 -1
  142. package/agent-docs/author/frontmatter.sections/related-metadata-tasks.md +1 -1
  143. package/agent-docs/author/frontmatter.sections/related-reading.md +1 -1
  144. package/agent-docs/author/frontmatter.sections/required-after-inheritance.md +1 -1
  145. package/agent-docs/author/frontmatter.sections/seo-fields.md +2 -2
  146. package/agent-docs/author/frontmatter.sections/validation-rules.md +3 -3
  147. package/agent-docs/author/markdown-metadata.md +20 -20
  148. package/agent-docs/author/navigation.md +12 -12
  149. package/agent-docs/author/navigation.sections/arrange-authored-pages.md +4 -4
  150. package/agent-docs/author/navigation.sections/fill-an-api-tag-group.md +2 -2
  151. package/agent-docs/author/navigation.sections/hide-group-page-counts.md +4 -4
  152. package/agent-docs/author/navigation.sections/html-markdown-and-agents.md +4 -4
  153. package/agent-docs/author/navigation.sections/local-api-preview.md +2 -2
  154. package/agent-docs/author/navigation.sections/mix-guides-and-api-references.md +3 -3
  155. package/agent-docs/author/navigation.sections/optionally-split-a-large-menu-into-files.md +2 -2
  156. package/agent-docs/author/navigation.sections/reach-navigation-while-reading.md +2 -2
  157. package/agent-docs/author/navigation.sections/related-reading.md +2 -2
  158. package/agent-docs/author/navigation.sections/split-navigation-into-tabs.md +4 -4
  159. package/agent-docs/author/navigation.sections/subject-lifecycle-labels.md +3 -3
  160. package/agent-docs/author/reader-views.md +9 -9
  161. package/agent-docs/author/reader-views.sections/configure-the-choices.md +2 -2
  162. package/agent-docs/author/reader-views.sections/connect-your-own-control.md +1 -1
  163. package/agent-docs/author/reader-views.sections/how-it-works-for-agents.md +3 -3
  164. package/agent-docs/author/reader-views.sections/mark-pages.md +3 -3
  165. package/agent-docs/author/reader-views.sections/mark-sections-and-add-an-entry-choice.md +2 -2
  166. package/agent-docs/author/reader-views.sections/place-filter-controls.md +2 -2
  167. package/agent-docs/author/reader-views.sections/try-the-controls-here.md +2 -2
  168. package/agent-docs/author/recipe-drafts.md +5 -5
  169. package/agent-docs/author/recipe-drafts.sections/1-write-one-reusable-step.md +2 -2
  170. package/agent-docs/author/recipe-drafts.sections/2-list-the-steps-for-one-complete-goal.md +2 -2
  171. package/agent-docs/author/recipe-drafts.sections/3-generate-a-draft-and-review-it.md +1 -1
  172. package/agent-docs/author/recipe-drafts.sections/4-maintain-shoalrun-s-published-recipe-snapshots.md +2 -2
  173. package/agent-docs/author/recipe-drafts.sections/related-reading.md +1 -1
  174. package/agent-docs/author/recipe-drafts.sections/start-an-ingredient-from-an-api-example.md +2 -2
  175. package/agent-docs/author/recipes.md +9 -9
  176. package/agent-docs/author/recipes.sections/how-agents-use-this.md +3 -3
  177. package/agent-docs/author/recipes.sections/one-example-from-shoalrun.md +3 -3
  178. package/agent-docs/author/recipes.sections/related-reading.md +2 -2
  179. package/agent-docs/author/recipes.sections/try-a-complete-workflow.md +3 -3
  180. package/agent-docs/author/recipes.sections/use-recipes-for-task-oriented-how-tos.md +4 -4
  181. package/agent-docs/author/recipes.sections/what-changing-an-ingredient-updates.md +3 -3
  182. package/agent-docs/author/recipes.sections/what-each-file-does.md +2 -2
  183. package/agent-docs/author/recipes.sections/what-happens-and-when.md +3 -3
  184. package/agent-docs/author/related-reading.md +11 -11
  185. package/agent-docs/author/related-reading.sections/automatic-footers.md +3 -3
  186. package/agent-docs/author/related-reading.sections/declare-relationships.md +3 -3
  187. package/agent-docs/author/related-reading.sections/display-related-documents.md +3 -3
  188. package/agent-docs/author/related-reading.sections/html-markdown-and-agents.md +1 -1
  189. package/agent-docs/author/related-reading.sections/inspect-output-and-changes.md +2 -2
  190. package/agent-docs/author/related-reading.sections/reading-paths-in-section-markdown.md +3 -3
  191. package/agent-docs/author/related-reading.sections/related-reading.md +1 -1
  192. package/agent-docs/author/related-reading.sections/where-relationship-explanations-come-from.md +2 -2
  193. package/agent-docs/author/release-notes.md +8 -8
  194. package/agent-docs/author/search.md +82 -29
  195. package/agent-docs/author/search.sections/agent-and-mcp-search-scope.md +52 -0
  196. package/agent-docs/author/search.sections/choose-a-provider.md +8 -7
  197. package/agent-docs/author/search.sections/cli-and-mcp-ranking-details.md +4 -4
  198. package/agent-docs/author/search.sections/enable-included-semantic-search.md +66 -0
  199. package/agent-docs/author/search.sections/hosted-semantic-search-limits.md +3 -3
  200. package/agent-docs/author/search.sections/html-markdown-and-agents.md +3 -3
  201. package/agent-docs/author/search.sections/lexical-search.md +6 -6
  202. package/agent-docs/author/search.sections/local-semantic-preview.md +3 -3
  203. package/agent-docs/author/search.sections/read-a-search-result-with-an-agent.md +2 -2
  204. package/agent-docs/author/search.sections/related-reading.md +2 -2
  205. package/agent-docs/author/search.sections/reuse-the-lexical-index.md +5 -5
  206. package/agent-docs/author/search.sections/turn-search-off.md +3 -3
  207. package/agent-docs/author/search.sections/use-the-search-box.md +2 -2
  208. package/agent-docs/author/search.sections/write-a-custom-provider.md +11 -11
  209. package/agent-docs/author/snippets.md +3 -3
  210. package/agent-docs/author/taxonomy.md +3 -3
  211. package/agent-docs/author/templates.md +16 -14
  212. package/agent-docs/author/templates.sections/built-in-feature-templates.md +2 -2
  213. package/agent-docs/author/templates.sections/built-in-templates.md +2 -2
  214. package/agent-docs/author/templates.sections/choose-formatting-enforcement-for-your-project.md +7 -7
  215. package/agent-docs/author/templates.sections/create-or-edit-a-project-template.md +8 -6
  216. package/agent-docs/author/templates.sections/keep-the-four-shapes-distinct.md +2 -2
  217. package/agent-docs/author/templates.sections/project-added-templates.md +3 -3
  218. package/agent-docs/author/templates.sections/related-reading.md +2 -2
  219. package/agent-docs/author/templates.sections/scaffold-a-page.md +2 -2
  220. package/agent-docs/author/templates.sections/short-cli-and-derived-values.md +3 -3
  221. package/agent-docs/author/templates.sections/what-every-template-gives-you.md +3 -3
  222. package/agent-docs/author/workspace/commands.md +4 -4
  223. package/agent-docs/author/workspace.md +7 -7
  224. package/agent-docs/author/writing-style.md +33 -18
  225. package/agent-docs/author/writing-style.sections/adapt-this-example.md +2 -2
  226. package/agent-docs/author/writing-style.sections/choose-components-by-reader-need.md +3 -3
  227. package/agent-docs/author/writing-style.sections/evidence-and-uncertainty.md +4 -4
  228. package/agent-docs/author/writing-style.sections/example-audience-and-scope.md +2 -2
  229. package/agent-docs/author/writing-style.sections/feature-availability.md +20 -7
  230. package/agent-docs/author/writing-style.sections/ingredients-recipes-and-cookbooks.md +5 -5
  231. package/agent-docs/author/writing-style.sections/page-purpose-and-structure.md +4 -4
  232. package/agent-docs/author/writing-style.sections/procedures-and-examples.md +4 -4
  233. package/agent-docs/author/writing-style.sections/related-reading.md +2 -2
  234. package/agent-docs/author/writing-style.sections/review-a-draft.md +3 -3
  235. package/agent-docs/author/writing-style.sections/reviewed-writing-examples.md +2 -2
  236. package/agent-docs/author/writing-style.sections/voice-and-explanations.md +4 -2
  237. package/agent-docs/changelog/2026-10-14-agent-readiness.md +2 -2
  238. package/agent-docs/changelog/2026-10-15-evaluation-builds.md +9 -9
  239. package/agent-docs/changelog/2026-10-16-navigation-layouts.md +4 -4
  240. package/agent-docs/changelog/2026-10-17-mcp-hosting.md +2 -2
  241. package/agent-docs/changelog/2026-10-18-search-and-tooltips.md +3 -3
  242. package/agent-docs/changelog/2026-10-19-visual-navigation.md +3 -3
  243. package/agent-docs/changelog/2026-10-25.md +2 -2
  244. package/agent-docs/changelog/2026-10-26.md +4 -4
  245. package/agent-docs/changelog/2026-10-27.md +1 -1
  246. package/agent-docs/changelog/2026-10-28.md +3 -3
  247. package/agent-docs/changelog/2026-10-30.md +1 -1
  248. package/agent-docs/changelog/2026-11-03.md +5 -5
  249. package/agent-docs/changelog/2026-11-04-runtime-packaging.md +46 -0
  250. package/agent-docs/changelog/authoring-preview.md +3 -3
  251. package/agent-docs/changelog/authoring-search.md +1 -1
  252. package/agent-docs/changelog/authoring-tools.md +2 -2
  253. package/agent-docs/changelog/product-publications.md +60 -0
  254. package/agent-docs/changelog/working-tree-skill.md +1 -1
  255. package/agent-docs/changelog.md +17 -1
  256. package/agent-docs/chat/checks.md +11 -11
  257. package/agent-docs/chat/checks.sections/answer-ahead-of-time.md +1 -1
  258. package/agent-docs/chat/checks.sections/answer-for-one-audience.md +2 -2
  259. package/agent-docs/chat/checks.sections/answer-without-a-model.md +2 -2
  260. package/agent-docs/chat/checks.sections/follow-up-questions.md +2 -2
  261. package/agent-docs/chat/checks.sections/how-an-answer-is-checked.md +3 -3
  262. package/agent-docs/chat/checks.sections/questions-with-several-parts.md +3 -3
  263. package/agent-docs/chat/checks.sections/related-reading.md +1 -1
  264. package/agent-docs/chat/checks.sections/reuse-answers.md +4 -4
  265. package/agent-docs/chat/host.md +8 -8
  266. package/agent-docs/chat/host.sections/cap-the-daily-spend.md +2 -2
  267. package/agent-docs/chat/host.sections/keep-a-record-of-questions.md +3 -3
  268. package/agent-docs/chat/host.sections/related-reading.md +2 -2
  269. package/agent-docs/chat/passage-index.md +31 -27
  270. package/agent-docs/chat/passage-index.sections/build-the-index.md +3 -3
  271. package/agent-docs/chat/passage-index.sections/embed-passages.md +4 -4
  272. package/agent-docs/chat/passage-index.sections/how-the-default-chunker-splits-a-page.md +3 -3
  273. package/agent-docs/chat/passage-index.sections/limits.md +3 -3
  274. package/agent-docs/chat/passage-index.sections/passage-ids-and-links.md +14 -10
  275. package/agent-docs/chat/passage-index.sections/related-reading.md +3 -3
  276. package/agent-docs/chat/passage-index.sections/what-a-passage-contains.md +19 -19
  277. package/agent-docs/chat/prepared-answers.md +4 -4
  278. package/agent-docs/chat/settings.md +3 -3
  279. package/agent-docs/chat/settings.sections/choose-the-scorer.md +1 -1
  280. package/agent-docs/chat/settings.sections/configure-chat.md +1 -1
  281. package/agent-docs/chat/settings.sections/configure-retrieval.md +1 -1
  282. package/agent-docs/chat/settings.sections/related-reading.md +1 -1
  283. package/agent-docs/chat/settings.sections/send-extra-request-fields.md +2 -2
  284. package/agent-docs/chat/settings.sections/use-more-than-one-model.md +2 -2
  285. package/agent-docs/chat/settings.sections/when-the-scorer-is-down.md +1 -1
  286. package/agent-docs/chat/setup.md +2 -2
  287. package/agent-docs/chat.md +3 -3
  288. package/agent-docs/cli.md +73 -59
  289. package/agent-docs/cli.sections/audit-a-project-and-api-sources.md +11 -7
  290. package/agent-docs/cli.sections/author-pages.md +16 -12
  291. package/agent-docs/cli.sections/build-and-serve.md +30 -18
  292. package/agent-docs/cli.sections/inspect-config-and-operations.md +13 -9
  293. package/agent-docs/cli.sections/npm-scripts-in-this-repository.md +7 -3
  294. package/agent-docs/cli.sections/related-reading.md +6 -2
  295. package/agent-docs/cli.sections/search-and-chat.md +24 -18
  296. package/agent-docs/cli.sections/start-a-project.md +7 -3
  297. package/agent-docs/cli.sections/working-tree-authoring-tools.md +7 -3
  298. package/agent-docs/concepts.md +2 -2
  299. package/agent-docs/config/apis.md +2 -2
  300. package/agent-docs/config/content.md +3 -3
  301. package/agent-docs/config/content.sections/authoring.md +3 -3
  302. package/agent-docs/config/content.sections/badges.md +1 -1
  303. package/agent-docs/config/content.sections/callouts.md +1 -1
  304. package/agent-docs/config/content.sections/cookbooks.md +1 -1
  305. package/agent-docs/config/content.sections/frontmatter.md +1 -1
  306. package/agent-docs/config/content.sections/readerfilters.md +1 -1
  307. package/agent-docs/config/content.sections/related-reading.md +1 -1
  308. package/agent-docs/config/content.sections/relationships.md +1 -1
  309. package/agent-docs/config/content.sections/snippets.md +1 -1
  310. package/agent-docs/config/content.sections/templates.md +1 -1
  311. package/agent-docs/config/content.sections/variables.md +1 -1
  312. package/agent-docs/config/examples.md +4 -4
  313. package/agent-docs/config/examples.sections/feature-showcase.md +4 -4
  314. package/agent-docs/config/examples.sections/minimal-site.md +2 -2
  315. package/agent-docs/config/examples.sections/multilingual-help-center.md +2 -2
  316. package/agent-docs/config/examples.sections/parcel-api-documentation.md +2 -2
  317. package/agent-docs/config/examples.sections/related-reading.md +2 -2
  318. package/agent-docs/config/examples.sections/shared-company-preset.md +2 -2
  319. package/agent-docs/config/integrations.md +4 -4
  320. package/agent-docs/config/outputs.md +22 -16
  321. package/agent-docs/config/outputs.sections/exports.md +19 -13
  322. package/agent-docs/config/outputs.sections/metadata.md +2 -2
  323. package/agent-docs/config/outputs.sections/related-reading.md +1 -1
  324. package/agent-docs/config/publishing.md +29 -19
  325. package/agent-docs/config/publishing.sections/navigation.md +2 -2
  326. package/agent-docs/config/publishing.sections/redirects.md +8 -8
  327. package/agent-docs/config/publishing.sections/related-reading.md +2 -2
  328. package/agent-docs/config/site.md +42 -18
  329. package/agent-docs/config/site.sections/related-reading.md +1 -1
  330. package/agent-docs/config/site.sections/theme.md +1 -1
  331. package/agent-docs/config.md +2 -2
  332. package/agent-docs/configuration.md +19 -19
  333. package/agent-docs/configuration.sections/build-several-sites-from-shared-content.md +1 -1
  334. package/agent-docs/configuration.sections/change-inherited-lists-deliberately.md +5 -5
  335. package/agent-docs/configuration.sections/extract-a-section-with-include.md +1 -1
  336. package/agent-docs/configuration.sections/inspect-and-validate-changes.md +5 -5
  337. package/agent-docs/configuration.sections/related-reading.md +1 -1
  338. package/agent-docs/configuration.sections/separate-config-inheritance-from-page-metadata.md +5 -5
  339. package/agent-docs/configuration.sections/share-defaults-through-extends.md +3 -3
  340. package/agent-docs/configuration.sections/start-with-one-working-file.md +2 -2
  341. package/agent-docs/configuration.sections/understand-the-three-stages.md +3 -3
  342. package/agent-docs/configuration.sections/understand-where-paths-point.md +2 -2
  343. package/agent-docs/connect/mcp.md +24 -15
  344. package/agent-docs/content-delivery/agents.md +6 -6
  345. package/agent-docs/content-delivery/api.md +29 -16
  346. package/agent-docs/content-delivery/client.md +14 -8
  347. package/agent-docs/content-delivery/http-api/operations/get-content-representation-fa1d2e3f.md +10 -2
  348. package/agent-docs/content-delivery/http-api/operations/get-content-representation-head-4052375c.md +10 -2
  349. package/agent-docs/content-delivery/http-api/operations/get-content-resource-849f1c49.md +537 -3
  350. package/agent-docs/content-delivery/http-api/operations/get-content-resource-head-0a352acd.md +10 -2
  351. package/agent-docs/content-delivery/http-api/operations/list-content-resources-8e977ec7.md +545 -3
  352. package/agent-docs/content-delivery/http-api/operations/list-content-resources-head-b67cbad9.md +10 -2
  353. package/agent-docs/content-delivery/http-api.md +21 -7
  354. package/agent-docs/content-delivery/manifest.md +30 -8
  355. package/agent-docs/content-delivery/publish.md +5 -5
  356. package/agent-docs/content-delivery/render.md +6 -6
  357. package/agent-docs/content-delivery/rest.md +16 -8
  358. package/agent-docs/content-delivery/sections.md +11 -11
  359. package/agent-docs/content-delivery/select.md +6 -6
  360. package/agent-docs/content-delivery.md +4 -4
  361. package/agent-docs/contribute/agent-skills.md +3 -3
  362. package/agent-docs/cookbooks/authoring.md +3 -3
  363. package/agent-docs/cookbooks/site-workflows.md +2 -2
  364. package/agent-docs/cookbooks/welcome-email.md +14 -11
  365. package/agent-docs/documents.json +2445 -1942
  366. package/agent-docs/example-api/cedar.md +4 -4
  367. package/agent-docs/features.md +49 -0
  368. package/agent-docs/glossary.md +22 -22
  369. package/agent-docs/index.md +5 -5
  370. package/agent-docs/ingredients/audit-site.md +2 -2
  371. package/agent-docs/ingredients/build-site.md +2 -2
  372. package/agent-docs/ingredients/complete-page.md +2 -2
  373. package/agent-docs/ingredients/refresh-agent-bundle.md +2 -2
  374. package/agent-docs/non-goals.md +4 -4
  375. package/agent-docs/provenance.json +10 -4
  376. package/agent-docs/publish/agent-discovery.md +8 -2
  377. package/agent-docs/publish/agent-friendliness.md +21 -21
  378. package/agent-docs/publish/agent-friendliness.sections/discover-a-page-with-a-small-context-budget.md +5 -5
  379. package/agent-docs/publish/agent-friendliness.sections/distinguish-examples-from-a-real-service.md +5 -5
  380. package/agent-docs/publish/agent-friendliness.sections/evidence-has-a-scope.md +5 -5
  381. package/agent-docs/publish/agent-friendliness.sections/keep-shared-instructions-complete.md +5 -5
  382. package/agent-docs/publish/agent-friendliness.sections/related-reading.md +3 -3
  383. package/agent-docs/publish/agent-friendliness.sections/secret-handshake.md +3 -3
  384. package/agent-docs/publish/agent-friendliness.sections/try-the-page-controls.md +3 -3
  385. package/agent-docs/publish/agent-friendliness.sections/use-the-transport-your-client-supports.md +4 -4
  386. package/agent-docs/publish/agent-friendliness.sections/verify-the-page-and-detect-changes.md +9 -9
  387. package/agent-docs/publish/agent-friendliness.sections/what-an-agent-reads.md +5 -5
  388. package/agent-docs/publish/agent-friendliness.sections/what-happens-to-an-unsupported-component.md +4 -4
  389. package/agent-docs/publish/api-references.md +5 -5
  390. package/agent-docs/publish/api-references.sections/author-the-reference-page.md +2 -2
  391. package/agent-docs/publish/api-references.sections/build-and-verify-the-output.md +3 -3
  392. package/agent-docs/publish/api-references.sections/inspect-the-machine-readable-contract.md +2 -2
  393. package/agent-docs/publish/api-references.sections/next-steps.md +2 -2
  394. package/agent-docs/publish/api-references.sections/preview-a-small-api-reference.md +2 -2
  395. package/agent-docs/publish/api-references.sections/put-the-spec-in-your-project.md +2 -2
  396. package/agent-docs/publish/api-references.sections/register-the-operation.md +2 -2
  397. package/agent-docs/publish/api-references.sections/related-reading.md +2 -2
  398. package/agent-docs/publish/api-references.sections/review-imported-content-before-publishing.md +3 -3
  399. package/agent-docs/publish/api-references.sections/what-readers-get.md +3 -3
  400. package/agent-docs/publish/audit.md +8 -8
  401. package/agent-docs/publish/audit.sections/add-project-tests.md +2 -2
  402. package/agent-docs/publish/audit.sections/check-agent-evaluation-reports.md +2 -2
  403. package/agent-docs/publish/audit.sections/check-before-pushing.md +3 -3
  404. package/agent-docs/publish/audit.sections/connect-a-documentation-test-suite.md +2 -2
  405. package/agent-docs/publish/audit.sections/read-the-report.md +3 -3
  406. package/agent-docs/publish/audit.sections/related-reading.md +1 -1
  407. package/agent-docs/publish/content-export.md +37 -15
  408. package/agent-docs/publish/content-export.sections/assets-downloads-and-notices.md +4 -4
  409. package/agent-docs/publish/content-export.sections/check-the-result.md +2 -2
  410. package/agent-docs/publish/content-export.sections/inspect-the-manifest.md +3 -3
  411. package/agent-docs/publish/content-export.sections/prerequisites.md +4 -4
  412. package/agent-docs/publish/content-export.sections/related-reading.md +2 -2
  413. package/agent-docs/publish/content-export.sections/review-exported-api-material.md +3 -3
  414. package/agent-docs/publish/content-export.sections/try-the-help-drawer-example.md +2 -2
  415. package/agent-docs/publish/content-export.sections/what-the-representations-retain.md +4 -4
  416. package/agent-docs/publish/content-negotiation.md +10 -10
  417. package/agent-docs/publish/content-negotiation.sections/hosting-contract.md +2 -2
  418. package/agent-docs/publish/content-negotiation.sections/missing-pages.md +3 -3
  419. package/agent-docs/publish/content-negotiation.sections/related-reading.md +1 -1
  420. package/agent-docs/publish/content-negotiation.sections/validators-and-manifest-links.md +2 -2
  421. package/agent-docs/publish/content-negotiation.sections/verify-the-deployed-url.md +2 -2
  422. package/agent-docs/publish/content-negotiation.sections/what-if-the-host-cannot-negotiate.md +3 -3
  423. package/agent-docs/publish/content-negotiation.sections/what-shoalrun-builds-and-what-the-host-does.md +2 -2
  424. package/agent-docs/publish/content-negotiation.sections/why-this-matters.md +2 -2
  425. package/agent-docs/publish/deployment-check.md +6 -6
  426. package/agent-docs/publish/deployment-profiles.md +60 -26
  427. package/agent-docs/publish/deployment-profiles.sections/before-you-begin.md +5 -5
  428. package/agent-docs/publish/deployment-profiles.sections/build-and-inspect-the-edition.md +9 -9
  429. package/agent-docs/publish/deployment-profiles.sections/check-the-result.md +7 -7
  430. package/agent-docs/publish/deployment-profiles.sections/choose-navigation-labels.md +6 -6
  431. package/agent-docs/publish/deployment-profiles.sections/current-limits.md +7 -7
  432. package/agent-docs/publish/deployment-profiles.sections/define-the-shared-sku-manifest.md +6 -6
  433. package/agent-docs/publish/deployment-profiles.sections/html-markdown-and-agents.md +7 -7
  434. package/agent-docs/publish/deployment-profiles.sections/mark-pages-and-shared-sections.md +13 -13
  435. package/agent-docs/publish/deployment-profiles.sections/preview-and-edit-a-customer-edition.md +55 -0
  436. package/agent-docs/publish/deployment-profiles.sections/related-reading.md +6 -6
  437. package/agent-docs/publish/deployment-profiles.sections/select-each-product-release.md +55 -0
  438. package/agent-docs/publish/deployment-profiles.sections/supply-the-profile-from-the-deployment.md +6 -6
  439. package/agent-docs/publish/evals.md +16 -16
  440. package/agent-docs/publish/evals.sections/add-the-audit-hook.md +5 -5
  441. package/agent-docs/publish/evals.sections/check-the-report.md +4 -4
  442. package/agent-docs/publish/evals.sections/define-a-task-file.md +5 -5
  443. package/agent-docs/publish/evals.sections/diagnose-a-different-build.md +5 -5
  444. package/agent-docs/publish/evals.sections/prepare-a-report-for-the-built-site.md +5 -5
  445. package/agent-docs/publish/evals.sections/related-reading.md +3 -3
  446. package/agent-docs/publish/evals.sections/run-and-review-the-tasks.md +4 -4
  447. package/agent-docs/publish/evals.sections/shoalrun-s-own-example.md +6 -6
  448. package/agent-docs/publish/host-adapters.md +6 -6
  449. package/agent-docs/publish/manni.md +16 -16
  450. package/agent-docs/publish/manni.sections/check-the-result.md +3 -3
  451. package/agent-docs/publish/manni.sections/how-this-site-uses-manni.md +6 -6
  452. package/agent-docs/publish/manni.sections/optional-custom-policies.md +4 -4
  453. package/agent-docs/publish/manni.sections/prerequisites.md +2 -2
  454. package/agent-docs/publish/mcp-analytics.md +12 -12
  455. package/agent-docs/publish/mcp-analytics.sections/adapter-exports.md +4 -4
  456. package/agent-docs/publish/mcp-analytics.sections/enable-analytics.md +4 -4
  457. package/agent-docs/publish/mcp-analytics.sections/event-fields-and-service-mappings.md +4 -4
  458. package/agent-docs/publish/mcp-analytics.sections/optionally-collect-intent-and-group-calls.md +4 -4
  459. package/agent-docs/publish/mcp-analytics.sections/optionally-identify-the-client-and-model.md +5 -5
  460. package/agent-docs/publish/mcp-analytics.sections/related-reading.md +3 -3
  461. package/agent-docs/publish/mcp-analytics.sections/safeguards-and-limits.md +5 -5
  462. package/agent-docs/publish/mcp.md +56 -29
  463. package/agent-docs/publish/mcp.sections/check-budgets-and-errors.md +8 -8
  464. package/agent-docs/publish/mcp.sections/choose-the-documentation-source.md +4 -4
  465. package/agent-docs/publish/mcp.sections/configure-the-client.md +4 -4
  466. package/agent-docs/publish/mcp.sections/discover-product-releases-before-searching.md +52 -0
  467. package/agent-docs/publish/mcp.sections/generate-a-vercel-endpoint.md +6 -6
  468. package/agent-docs/publish/mcp.sections/html-markdown-and-agents.md +38 -0
  469. package/agent-docs/publish/mcp.sections/related-reading.md +3 -3
  470. package/agent-docs/publish/mcp.sections/search-then-read.md +13 -12
  471. package/agent-docs/publish/mcp.sections/serve-a-public-endpoint-on-node.md +12 -8
  472. package/agent-docs/publish/mcp.sections/verify-the-connection.md +4 -4
  473. package/agent-docs/publish/mcp.sections/why-offer-mcp-for-public-docs.md +4 -4
  474. package/agent-docs/publish/openapi-extension-mappings.md +12 -12
  475. package/agent-docs/publish/output.md +20 -20
  476. package/agent-docs/publish/output.sections/api-contracts.md +1 -1
  477. package/agent-docs/publish/output.sections/code-highlighting.md +1 -1
  478. package/agent-docs/publish/output.sections/current-limits.md +1 -1
  479. package/agent-docs/publish/output.sections/incremental-sync.md +4 -4
  480. package/agent-docs/publish/output.sections/manifest-records-and-sections.md +3 -3
  481. package/agent-docs/publish/output.sections/navigation-section-indexes.md +1 -1
  482. package/agent-docs/publish/output.sections/page-formats.md +2 -2
  483. package/agent-docs/publish/output.sections/published-output-contract.md +5 -5
  484. package/agent-docs/publish/output.sections/reader-appearance-and-controls.md +1 -1
  485. package/agent-docs/publish/output.sections/related-reading.md +1 -1
  486. package/agent-docs/publish/output.sections/response-identity.md +1 -1
  487. package/agent-docs/publish/output.sections/site-files.md +6 -6
  488. package/agent-docs/publish/output.sections/validate-an-existing-build-locally.md +3 -3
  489. package/agent-docs/publish/output.sections/where-files-go.md +3 -3
  490. package/agent-docs/publish/publications.md +108 -19
  491. package/agent-docs/publish/publications.sections/add-a-language.md +60 -0
  492. package/agent-docs/publish/publications.sections/change-just-one-part-of-a-shared-page.md +63 -0
  493. package/agent-docs/publish/publications.sections/give-each-api-version-its-own-contract.md +34 -0
  494. package/agent-docs/publish/publications.sections/keep-an-unchanged-page-in-one-file.md +53 -0
  495. package/agent-docs/publish/publications.sections/publish-versions-without-a-product-catalog.md +49 -0
  496. package/agent-docs/publish/publications.sections/related-reading.md +42 -0
  497. package/agent-docs/publish/publications.sections/version-products-independently.md +115 -0
  498. package/agent-docs/publish/publications.sections/what-agents-receive.md +38 -0
  499. package/agent-docs/publish/revisions.md +4 -4
  500. package/agent-docs/publish/seo.md +10 -10
  501. package/agent-docs/publish/seo.sections/related-reading.md +2 -2
  502. package/agent-docs/publish/seo.sections/set-the-public-address.md +3 -3
  503. package/agent-docs/publish/seo.sections/what-agents-receive.md +3 -3
  504. package/agent-docs/publish/seo.sections/what-the-build-adds.md +2 -2
  505. package/agent-docs/publish/seo.sections/write-the-page-title-and-summary.md +2 -2
  506. package/agent-docs/publish/single-source-sites.md +5 -5
  507. package/agent-docs/publish/troubleshooting.md +10 -10
  508. package/agent-docs/publish/vercel.md +5 -5
  509. package/agent-docs/publish/vercel.sections/check-the-deployment.md +1 -1
  510. package/agent-docs/publish/vercel.sections/include-an-mcp-endpoint.md +2 -2
  511. package/agent-docs/publish/vercel.sections/prepare-your-project.md +2 -2
  512. package/agent-docs/publish/vercel.sections/related-reading.md +1 -1
  513. package/agent-docs/publish.md +2 -2
  514. package/agent-docs/recipes/add-page.md +5 -5
  515. package/agent-docs/recipes/add-page.sections/audit-the-shoalrun-docs-project.md +2 -2
  516. package/agent-docs/recipes/add-page.sections/before-you-start.md +1 -1
  517. package/agent-docs/recipes/add-page.sections/build-the-shoalrun-docs-site.md +2 -2
  518. package/agent-docs/recipes/add-page.sections/check-agent-search-and-page-lookup.md +1 -1
  519. package/agent-docs/recipes/add-page.sections/check-the-built-page-artifacts.md +1 -1
  520. package/agent-docs/recipes/add-page.sections/check-the-outcome.md +1 -1
  521. package/agent-docs/recipes/add-page.sections/complete-the-guide-and-add-navigation.md +2 -2
  522. package/agent-docs/recipes/add-page.sections/install-the-site-dependencies.md +1 -1
  523. package/agent-docs/recipes/add-page.sections/regenerate-the-agent-documentation-bundle.md +2 -2
  524. package/agent-docs/recipes/add-page.sections/related-reading.md +1 -1
  525. package/agent-docs/recipes/add-page.sections/scaffold-a-new-guide.md +1 -1
  526. package/agent-docs/recipes/audit-docs.md +4 -4
  527. package/agent-docs/recipes/build-docs.md +2 -2
  528. package/agent-docs/recipes/preview-hybrid-search.md +5 -5
  529. package/agent-docs/recipes/preview-page.md +2 -2
  530. package/agent-docs/recipes/queue-email.md +3 -3
  531. package/agent-docs/recipes/refresh-agent-docs.md +4 -4
  532. package/agent-docs/recipes/send-welcome-email.md +15 -15
  533. package/agent-docs/reference/agent-skills.md +7 -7
  534. package/agent-docs/search-and-chat.md +4 -4
  535. package/agent-docs/search-index.json +1 -1
  536. package/agent-docs/start.md +5 -5
  537. package/agent-docs/start.sections/add-the-page-to-navigation.md +3 -3
  538. package/agent-docs/start.sections/build-and-check-both-outputs.md +3 -3
  539. package/agent-docs/start.sections/build-this-site.md +2 -2
  540. package/agent-docs/start.sections/check-writing-style.md +2 -2
  541. package/agent-docs/start.sections/create-a-page.md +2 -2
  542. package/agent-docs/start.sections/make-it-yours.md +2 -2
  543. package/agent-docs/start.sections/migrating-from-github-packages.md +2 -2
  544. package/agent-docs/start.sections/prerequisites.md +2 -2
  545. package/agent-docs/start.sections/related-reading.md +2 -2
  546. package/agent-docs/start.sections/start-your-own-project.md +3 -3
  547. package/agent-docs/status.md +14 -4
  548. package/agent-docs/styling/color-modes.md +2 -2
  549. package/agent-docs/styling/footer.md +2 -2
  550. package/agent-docs/styling/header.md +2 -2
  551. package/agent-docs/styling/layouts.md +3 -3
  552. package/agent-docs/styling/layouts.sections/build-a-landing-page.md +1 -1
  553. package/agent-docs/styling/layouts.sections/build-a-splash-page.md +1 -1
  554. package/agent-docs/styling/layouts.sections/control-navigation-tabs.md +2 -2
  555. package/agent-docs/styling/layouts.sections/customize-the-hero.md +1 -1
  556. package/agent-docs/styling/layouts.sections/hero.md +1 -1
  557. package/agent-docs/styling/layouts.sections/hide-the-table-of-contents-or-give-content-more-room.md +1 -1
  558. package/agent-docs/styling/layouts.sections/html-markdown-and-agents.md +2 -2
  559. package/agent-docs/styling/layouts.sections/related-reading.md +1 -1
  560. package/agent-docs/styling/palettes.md +3 -3
  561. package/agent-docs/styling/share-images.md +3 -3
  562. package/agent-docs/styling/themes.md +2 -2
  563. package/agent-docs/styling/try.md +2 -2
  564. package/agent-docs/what-is-shoalrun.md +7 -3
  565. package/assets/ask-widget.js +20 -6
  566. package/assets/navigation.js +5 -0
  567. package/dist/ai-directory.d.ts +1 -0
  568. package/dist/ai-directory.js +12 -0
  569. package/dist/answer-cards.js +1 -1
  570. package/dist/api-materialize.d.ts +2 -1
  571. package/dist/api-materialize.js +21 -9
  572. package/dist/api-publication-plan.d.ts +2 -0
  573. package/dist/api-publication-plan.js +23 -7
  574. package/dist/api-publication-review.js +4 -3
  575. package/dist/api-selection.d.ts +5 -2
  576. package/dist/api-selection.js +18 -11
  577. package/dist/artifact-bundle.js +9 -6
  578. package/dist/ask-function.d.ts +4 -18
  579. package/dist/ask-function.js +12 -71
  580. package/dist/ask-runtime.d.ts +46 -0
  581. package/dist/ask-runtime.js +101 -0
  582. package/dist/ask-setup.d.ts +3 -42
  583. package/dist/ask-setup.js +5 -93
  584. package/dist/authored-change.js +2 -1
  585. package/dist/authoring-project.js +1 -1
  586. package/dist/cards.js +2 -1
  587. package/dist/cli-discovery.d.ts +2 -2
  588. package/dist/cli-discovery.js +9 -4
  589. package/dist/cli.js +48 -23
  590. package/dist/compiler-config.d.ts +17 -0
  591. package/dist/compiler-config.js +43 -2
  592. package/dist/compiler.d.ts +21 -0
  593. package/dist/compiler.js +16 -12
  594. package/dist/component-transform.d.ts +2 -4
  595. package/dist/component-transform.js +20 -7
  596. package/dist/config.d.ts +1 -0
  597. package/dist/config.js +2 -1
  598. package/dist/content-delivery-contract.d.ts +2 -1
  599. package/dist/content-delivery-validation.d.ts +2 -2
  600. package/dist/content-delivery-validation.js +6 -4
  601. package/dist/content-export-command.d.ts +1 -1
  602. package/dist/content-export-command.js +4 -4
  603. package/dist/content-export-comparison.js +6 -5
  604. package/dist/content-export-config.js +3 -1
  605. package/dist/content-export.js +9 -8
  606. package/dist/content-rest-client.js +4 -2
  607. package/dist/content-rest-contract.d.ts +2 -2
  608. package/dist/content-rest-server.js +11 -6
  609. package/dist/content-source.d.ts +13 -0
  610. package/dist/content-source.js +5 -2
  611. package/dist/content-workspace.d.ts +12 -0
  612. package/dist/content-workspace.js +2 -1
  613. package/dist/content.js +3 -2
  614. package/dist/cookbook-chooser.js +2 -1
  615. package/dist/deployment-profile.d.ts +2 -1
  616. package/dist/deployment-profile.js +38 -8
  617. package/dist/dev.d.ts +3 -1
  618. package/dist/dev.js +99 -12
  619. package/dist/docs-author.js +2 -1
  620. package/dist/docs-command.js +2 -2
  621. package/dist/docs-eval.d.ts +1 -0
  622. package/dist/docs-eval.js +2 -2
  623. package/dist/docs-mcp.d.ts +1 -0
  624. package/dist/docs-mcp.js +10 -5
  625. package/dist/docs-tool.d.ts +4 -10
  626. package/dist/document-sync.d.ts +1 -0
  627. package/dist/document-sync.js +2 -2
  628. package/dist/documentation-core.d.ts +29 -10
  629. package/dist/documentation-core.js +38 -4
  630. package/dist/embeddings.d.ts +1 -1
  631. package/dist/embeddings.js +1 -1
  632. package/dist/freshness.js +2 -2
  633. package/dist/frontmatter.js +13 -7
  634. package/dist/function-package.js +5 -0
  635. package/dist/function-runtime.d.ts +24 -0
  636. package/dist/function-runtime.js +45 -0
  637. package/dist/index-build.d.ts +2 -2
  638. package/dist/index-build.js +5 -13
  639. package/dist/ingredient-draft.js +20 -10
  640. package/dist/mcp-analytics.d.ts +1 -0
  641. package/dist/mcp-artifacts.js +13 -4
  642. package/dist/mcp-config.d.ts +1 -0
  643. package/dist/mcp-config.js +3 -1
  644. package/dist/mcp-http.js +1 -1
  645. package/dist/page-materialization.d.ts +3 -4
  646. package/dist/page-materialization.js +15 -8
  647. package/dist/page-renderer.d.ts +6 -0
  648. package/dist/page-renderer.js +16 -5
  649. package/dist/project-navigation.js +2 -1
  650. package/dist/publication-identity.d.ts +12 -0
  651. package/dist/publication-identity.js +17 -0
  652. package/dist/publication-manifest.d.ts +24 -1
  653. package/dist/publication-manifest.js +14 -6
  654. package/dist/publication-plan.js +21 -9
  655. package/dist/publication-render.js +24 -8
  656. package/dist/recipe-draft.js +9 -6
  657. package/dist/retrieval-runtime.d.ts +5 -0
  658. package/dist/retrieval-runtime.js +21 -0
  659. package/dist/scaffold.d.ts +7 -4
  660. package/dist/scaffold.js +16 -16
  661. package/dist/search-function.d.ts +2 -0
  662. package/dist/search-function.js +30 -0
  663. package/dist/search-handler.js +2 -2
  664. package/dist/search-identifier-core.d.ts +4 -0
  665. package/dist/search-identifier-core.js +30 -0
  666. package/dist/search-identifier.d.ts +3 -3
  667. package/dist/search-identifier.js +7 -30
  668. package/dist/search-literal.js +1 -1
  669. package/dist/search-query.d.ts +4 -10
  670. package/dist/search-query.js +10 -9
  671. package/dist/search-results.js +1 -1
  672. package/dist/search-snippet.d.ts +1 -1
  673. package/dist/search-snippet.js +2 -14
  674. package/dist/search-text.d.ts +1 -0
  675. package/dist/search-text.js +14 -0
  676. package/dist/server.d.ts +8 -0
  677. package/dist/server.js +14 -3
  678. package/dist/subject-deprecation.js +2 -1
  679. package/dist/vercel-function.js +11 -3
  680. package/example-configs/products/README.md +37 -0
  681. package/example-configs/products/content/operations.mdx +50 -0
  682. package/example-configs/products/content/payments-v2.mdx +30 -0
  683. package/example-configs/products/content/payments-v3.mdx +38 -0
  684. package/example-configs/products/content/priority-settlement.mdx +23 -0
  685. package/example-configs/products/content/reporting-v1.mdx +36 -0
  686. package/example-configs/products/content/scheduled-exports.mdx +23 -0
  687. package/example-configs/products/docs.config.yaml +56 -0
  688. package/example-configs/products/profiles/all-releases.yaml +9 -0
  689. package/example-configs/products/profiles/customer-a.yaml +13 -0
  690. package/example-configs/products/profiles/customer-b.yaml +13 -0
  691. package/example-configs/products/skus.yaml +11 -0
  692. package/examples/content-delivery/preview.mjs +1 -1
  693. package/package.json +1 -1
  694. package/schemas/content-export.schema.json +41 -3
  695. package/schemas/content-rest.openapi.json +184 -37
  696. package/skills/shoalrun-author/SKILL.md +6 -2
  697. package/skills/shoalrun-author/references/customer-editions.md +34 -4
  698. package/skills/shoalrun-author/references/publications.md +60 -0
  699. package/skills/shoalrun-recipes/SKILL.md +2 -0
  700. package/skills/shoalrun-setup/SKILL.md +3 -1
  701. package/styles/header.css +3 -0
  702. package/styles/site.css +3 -0
  703. package/agent-docs/publish/content-export.sections/export-selected-pages.md +0 -116
@@ -1,9 +1,10 @@
1
1
  import { ContentDeliveryError, contentRefKey } from './content-delivery-contract.js';
2
+ import { validContentPublication } from './content-delivery-validation.js';
2
3
  import { contentResourceKey } from './content-rest-contract.js';
3
- const publicationKey = (publication) => JSON.stringify([publication.channel, publication.version, publication.language]);
4
+ const publicationKey = (publication) => JSON.stringify([publication.channel, publication.version, publication.language, ...(publication.product === undefined ? [] : [publication.product])]);
4
5
  const digest = async (bytes) => [...new Uint8Array(await crypto.subtle.digest('SHA-256', bytes))].map(value => value.toString(16).padStart(2, '0')).join('');
5
6
  const encoder = new TextEncoder();
6
- const validPublication = (value) => value && Object.keys(value).sort().join(',') === 'channel,language,version' && Object.values(value).every(part => typeof part === 'string' && part.length > 0 && part.length <= 2048);
7
+ const validPublication = validContentPublication;
7
8
  const canonical = (value) => Array.isArray(value) ? value.map(canonical) : value && typeof value === 'object' ? Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])])) : value;
8
9
  const same = (left, right) => JSON.stringify(canonical(left)) === JSON.stringify(canonical(right));
9
10
  /** Serve already-approved, pinned snapshots. The caller retains source ownership. */
@@ -38,16 +39,20 @@ export function createContentRestHandler(options) {
38
39
  const parts = url.pathname.slice(prefix.length).split('/').slice(1);
39
40
  if (parts.length !== 0 && parts.length !== 1 && !(parts.length === 3 && parts[1] === 'representations'))
40
41
  return error(404, 'not_found', 'Unknown content route.');
41
- const allowed = new Set(['channel', 'version', 'language', 'revision']);
42
+ const allowed = new Set(['channel', 'version', 'language', 'product', 'revision']);
42
43
  if ([...url.searchParams.keys()].some(key => !allowed.has(key) || url.searchParams.getAll(key).length !== 1))
43
44
  return error(400, 'invalid_request', 'Unknown or repeated query parameter.');
44
45
  const publication = Object.fromEntries(['channel', 'version', 'language'].map(key => [key, url.searchParams.get(key)]));
45
- if (Object.values(publication).some(value => !value || value.length > 2048))
46
+ if (url.searchParams.has('product'))
47
+ publication.product = url.searchParams.get('product');
48
+ if (!validPublication(publication))
46
49
  return error(400, 'invalid_request', 'channel, version, and language are required.');
47
50
  const revision = url.searchParams.get('revision');
48
51
  if (revision !== null && !/^[a-f0-9]{64}$/.test(revision) || parts.length > 0 && revision === null)
49
52
  return error(400, 'invalid_request', 'A valid revision is required for resource requests.');
50
53
  const selected = publications.get(publicationKey(publication));
54
+ if (!selected && publication.product === undefined && [...publications.values()].some(item => item.publication.product !== undefined && item.publication.channel === publication.channel && item.publication.version === publication.version && item.publication.language === publication.language))
55
+ return error(400, 'invalid_request', 'product is required for product-scoped publications.');
51
56
  if (!selected)
52
57
  return error(404, 'not_found', 'Publication not found.');
53
58
  if (revision !== null && revision !== selected.revision)
@@ -59,9 +64,9 @@ export function createContentRestHandler(options) {
59
64
  let body;
60
65
  let mediaType = 'application/json';
61
66
  if (!parts.length)
62
- body = JSON.stringify({ schemaVersion: 1, revision: selected.revision, publication: selected.publication, resources: selected.resources });
67
+ body = JSON.stringify({ schemaVersion: selected.publication.product === undefined ? 1 : 2, revision: selected.revision, publication: selected.publication, resources: selected.resources });
63
68
  else if (parts.length === 1)
64
- body = JSON.stringify({ schemaVersion: 1, revision: selected.revision, publication: selected.publication, ...resource });
69
+ body = JSON.stringify({ schemaVersion: selected.publication.product === undefined ? 1 : 2, revision: selected.revision, publication: selected.publication, ...resource });
65
70
  else {
66
71
  const format = parts[2];
67
72
  if (!['html', 'markdown'].includes(format) || !resource.resource.representations[format])
@@ -3,6 +3,7 @@ import type { SubjectDeprecation, ResolvedSubjectDeprecation } from './subject-d
3
3
  import type { ReaderSelection } from './reader-filters.js';
4
4
  import type { StandaloneSectionDeclaration } from './section-identity.js';
5
5
  export type Variant = {
6
+ product?: string;
6
7
  channel: string;
7
8
  version: string;
8
9
  language: string;
@@ -18,9 +19,14 @@ export type Frontmatter = {
18
19
  updated?: string;
19
20
  verified?: string;
20
21
  releaseVersion?: string;
22
+ availability?: {
23
+ since?: string;
24
+ through?: string;
25
+ };
21
26
  channel?: string;
22
27
  version?: string;
23
28
  publications?: Array<{
29
+ product?: string;
24
30
  channel: string;
25
31
  version: string;
26
32
  }>;
@@ -92,6 +98,13 @@ export type PublicationRoutingConfig = {
92
98
  versions: Record<string, {
93
99
  pathPrefix?: string;
94
100
  }>;
101
+ products?: Record<string, {
102
+ pathPrefix: string;
103
+ defaultVersion: string;
104
+ versions: Record<string, {
105
+ pathPrefix?: string;
106
+ }>;
107
+ }>;
95
108
  };
96
109
  };
97
110
  export declare function readDocument(file: string, frontmatterConfig?: unknown, enrich?: (source: Record<string, unknown>) => Promise<Record<string, unknown>>, sourceText?: string): Promise<{
@@ -26,7 +26,10 @@ export async function readDocument(file, frontmatterConfig, enrich, sourceText)
26
26
  }
27
27
  export function routeFor(frontmatter, variant, config) {
28
28
  const channel = config.publications.channels[variant.channel];
29
- const version = config.publications.versions[variant.version];
29
+ const product = variant.product === undefined ? undefined : config.publications.products?.[variant.product];
30
+ if (variant.product !== undefined && !product)
31
+ throw new Error(`Unknown publication product ${variant.product}`);
32
+ const version = (product?.versions ?? config.publications.versions)[variant.version];
30
33
  if (!channel || !version)
31
34
  throw new Error(`Unknown publication ${variant.channel}/${variant.version}`);
32
35
  const slug = frontmatter.slug;
@@ -35,7 +38,7 @@ export function routeFor(frontmatter, variant, config) {
35
38
  if (/^\/(?:\.well-known|api)(?:\/|$)/i.test(slug))
36
39
  throw new Error(`${frontmatter.id}: slug uses a reserved discovery path`);
37
40
  const languagePrefix = variant.language === defaultLanguage(config) ? '' : `/${variant.language}`;
38
- const parts = [normalizeBasePath(config.site.basePath), languagePrefix, channel.pathPrefix ?? '', version.pathPrefix ?? '', slug].filter(Boolean);
41
+ const parts = [normalizeBasePath(config.site.basePath), languagePrefix, product?.pathPrefix ?? '', channel.pathPrefix ?? '', version.pathPrefix ?? '', slug].filter(Boolean);
39
42
  const normalized = '/' + parts.join('/').replace(/\/+/g, '/').replace(/^\//, '').replace(/\/$/, '');
40
43
  return normalized === '/' ? '/' : normalized;
41
44
  }
@@ -47,7 +47,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
47
47
  path: string;
48
48
  [key: string]: unknown;
49
49
  };
50
+ product?: string;
50
51
  publications?: Array<{
52
+ product?: string;
51
53
  channel: string;
52
54
  version: string;
53
55
  source: {
@@ -90,7 +92,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
90
92
  path: string;
91
93
  [key: string]: unknown;
92
94
  };
95
+ product?: string;
93
96
  publications?: Array<{
97
+ product?: string;
94
98
  channel: string;
95
99
  version: string;
96
100
  source: {
@@ -134,7 +138,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
134
138
  path: string;
135
139
  [key: string]: unknown;
136
140
  };
141
+ product?: string;
137
142
  publications?: Array<{
143
+ product?: string;
138
144
  channel: string;
139
145
  version: string;
140
146
  source: {
@@ -173,7 +179,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
173
179
  path: string;
174
180
  [key: string]: unknown;
175
181
  };
182
+ product?: string;
176
183
  publications?: Array<{
184
+ product?: string;
177
185
  channel: string;
178
186
  version: string;
179
187
  source: {
@@ -216,7 +224,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
216
224
  path: string;
217
225
  [key: string]: unknown;
218
226
  };
227
+ product?: string;
219
228
  publications?: Array<{
229
+ product?: string;
220
230
  channel: string;
221
231
  version: string;
222
232
  source: {
@@ -270,7 +280,9 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
270
280
  path: string;
271
281
  [key: string]: unknown;
272
282
  };
283
+ product?: string;
273
284
  publications?: Array<{
285
+ product?: string;
274
286
  channel: string;
275
287
  version: string;
276
288
  source: {
@@ -1,3 +1,4 @@
1
+ import { documentKey } from './publication-identity.js';
1
2
  import { matchesFeatures } from './deployment-profile.js';
2
3
  import path from 'node:path';
3
4
  import { readFile } from 'node:fs/promises';
@@ -6,7 +7,7 @@ import { planAuthoredDocuments } from './publication-plan.js';
6
7
  import { materializeApiReferences } from './api-publication-plan.js';
7
8
  import { explainSegments } from './config.js';
8
9
  import { validateSnippetConfig } from './snippets.js';
9
- const keyFor = (id, variant) => `${id}|${variant.channel}|${variant.version}|${variant.language}`;
10
+ const keyFor = documentKey;
10
11
  /** Shared source resolution. No website navigation, styles, hosting or provider setup. */
11
12
  export async function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions }) {
12
13
  const { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir } = await planAuthoredDocuments({
package/dist/content.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { publicationKey } from './publication-identity.js';
1
2
  import { fictionalDocument, resolveLlmsDiscovery } from './llms-discovery.js';
2
3
  import YAML from 'yaml';
3
4
  import { nativePublicFields, protectedMetadataRoots, publicFrontmatterPaths } from './frontmatter.js';
@@ -8,7 +9,7 @@ export { transformMdx } from './component-transform.js';
8
9
  export { renderHtml } from './html-renderer.js';
9
10
  export { buildHtmlPage, shareCardText, typeLabel } from './page-renderer.js';
10
11
  // API separators are visually hidden punctuation; join them to the preceding text so search reads "integer; default: 0".
11
- const variantKey = (variant) => `${variant.channel}|${variant.version}|${variant.language}`;
12
+ const variantKey = publicationKey;
12
13
  const plainText = (html) => html.replace(/<(script|style)[^]*?<\/\1>/g, ' ').replace(/(?:<\/[a-z]+>)?<span class="api-separator">([^<]*)<\/span>/g, '$1').replace(/<[^>]+>/g, ' ')
13
14
  .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#x27;|&#39;/g, "'").replace(/&amp;/g, '&').replace(/\s+/g, ' ').trim();
14
15
  // One compact record per published page; headings allow results to deep-link into a section.
@@ -54,7 +55,7 @@ export function projectMetadata(doc, config) {
54
55
  throw new Error('Markdown metadata projection must be a mapping');
55
56
  const object = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
56
57
  const safePath = (value) => /^[A-Za-z_][A-Za-z0-9_-]*(?:\.[A-Za-z_][A-Za-z0-9_-]*)*$/.test(value);
57
- const publicationFields = new Set(['channel', 'version', 'language', 'canonicalUrl']);
58
+ const publicationFields = new Set(['product', 'channel', 'version', 'language', 'canonicalUrl']);
58
59
  const approved = publicFrontmatterPaths(config.frontmatter);
59
60
  const validateSource = (source) => {
60
61
  if (!safePath(source))
@@ -1,3 +1,4 @@
1
+ import { samePublication } from './publication-identity.js';
1
2
  const object = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
2
3
  const keys = (value, allowed) => Object.keys(value).every(key => allowed.includes(key));
3
4
  const validId = (value) => typeof value === 'string' && /^[a-z][a-z0-9-]*$/.test(value);
@@ -35,7 +36,7 @@ export function cookbookChooserComponent(node, file) {
35
36
  return { type: 'docCookbookChooser', id: attributes[0].value, sourceFile: file };
36
37
  }
37
38
  export function resolveCookbookTree(tree, current, documents, cookbooks, targets) {
38
- const sameVariant = (a, b) => a.variant.channel === b.variant.channel && a.variant.version === b.variant.version && a.variant.language === b.variant.language;
39
+ const sameVariant = (a, b) => samePublication(a.variant, b.variant);
39
40
  const walk = (node) => {
40
41
  if (node.type !== 'docCookbookChooser')
41
42
  return node.children ? { ...node, children: node.children.map(walk) } : node;
@@ -5,6 +5,7 @@ export type FeatureRequirements = {
5
5
  export type FeatureContext = {
6
6
  requireClassification?: boolean;
7
7
  classificationPublications?: Array<{
8
+ product?: string;
8
9
  channel: string;
9
10
  version: string;
10
11
  language: string;
@@ -49,4 +50,4 @@ export declare function profileSelection(resolution: ProfileResolution | undefin
49
50
  }[];
50
51
  } | undefined;
51
52
  /** A profile is data, never executable configuration or a directory to discover. */
52
- export declare function resolveDeploymentProfile(settings: unknown, config: Record<string, any>, declaringFile: string, profileFile?: string): Promise<ProfileResolution | undefined>;
53
+ export declare function resolveDeploymentProfile(settings: unknown, config: Record<string, any>, declaringFile: string, profileFile?: string, onDependency?: (file: string) => void): Promise<ProfileResolution | undefined>;
@@ -1,3 +1,5 @@
1
+ import { resolvePublication } from './compiler-config.js';
2
+ import { publicationKey } from './publication-identity.js';
1
3
  import { readFile, lstat, realpath } from 'node:fs/promises';
2
4
  import path from 'node:path';
3
5
  import { createHash } from 'node:crypto';
@@ -95,7 +97,7 @@ export function profileSelection(resolution) {
95
97
  return { schemaVersion: 1, profileDigest: resolution.digest, features: [...resolution.context.grants].sort(), provenance: resolution.context.provenance, decisions: resolution.context.decisions };
96
98
  }
97
99
  /** A profile is data, never executable configuration or a directory to discover. */
98
- export async function resolveDeploymentProfile(settings, config, declaringFile, profileFile) {
100
+ export async function resolveDeploymentProfile(settings, config, declaringFile, profileFile, onDependency) {
99
101
  if (settings === undefined) {
100
102
  if (profileFile)
101
103
  throw new Error('--profile requires profiles.manifest in the shared configuration');
@@ -108,6 +110,7 @@ export async function resolveDeploymentProfile(settings, config, declaringFile,
108
110
  if (settings[setting] !== undefined && typeof settings[setting] !== 'boolean')
109
111
  throw new Error(`profiles.${setting} must be boolean`);
110
112
  const manifestFile = path.resolve(path.dirname(declaringFile), settings.manifest);
113
+ onDependency?.(manifestFile);
111
114
  const manifestBytes = await readFile(manifestFile);
112
115
  const manifest = parseYaml(manifestBytes.toString('utf8'), manifestFile);
113
116
  keys(manifest, ['schemaVersion', 'features', 'skus'], 'SKU manifest');
@@ -142,13 +145,15 @@ export async function resolveDeploymentProfile(settings, config, declaringFile,
142
145
  const context = { features, digest, pruneNavigation: settings.pruneNavigation ?? false, decisions: [], provenance: Object.create(null) };
143
146
  context.requireClassification = settings.requireClassification ?? false;
144
147
  if (context.requireClassification)
145
- context.classificationPublications = (config.publications?.enabled ?? []).map((entry) => ({ channel: entry.channel, version: entry.version, language: entry.language ?? defaultLanguage(config) }));
148
+ context.classificationPublications = (config.publications?.enabled ?? []).map((entry) => resolvePublication(config.publications, entry, defaultLanguage(config)));
146
149
  if (!profileFile) {
147
150
  if (settings.required !== false)
148
151
  throw new Error('This project requires an explicit --profile FILE');
149
152
  return { context, overlay: {}, dependencies: [manifestFile], assetFiles: [], digest };
150
153
  }
154
+ onDependency?.(path.resolve(profileFile));
151
155
  const file = await realpath(path.resolve(profileFile));
156
+ onDependency?.(file);
152
157
  const bytes = await readFile(file);
153
158
  const profile = parseYaml(bytes.toString('utf8'), file);
154
159
  profileData(profile);
@@ -185,7 +190,12 @@ export async function resolveDeploymentProfile(settings, config, declaringFile,
185
190
  const overlay = {};
186
191
  const assetFiles = [];
187
192
  if (profile.site !== undefined) {
188
- keys(profile.site, ['title', 'origin', 'basePath', 'favicon', 'logo', 'header', 'footer', 'indexing'], 'Profile site');
193
+ keys(profile.site, ['title', 'origin', 'basePath', 'favicon', 'logo', 'header', 'footer', 'indexing', 'publicationSelector'], 'Profile site');
194
+ if (profile.site.publicationSelector !== undefined) {
195
+ keys(profile.site.publicationSelector, ['showLanguage'], 'Profile site.publicationSelector');
196
+ if (profile.site.publicationSelector.showLanguage !== undefined && typeof profile.site.publicationSelector.showLanguage !== 'boolean')
197
+ throw new Error('Profile site.publicationSelector.showLanguage must be boolean');
198
+ }
189
199
  if (profile.site.title !== undefined && (typeof profile.site.title !== 'string' || !profile.site.title.trim()))
190
200
  throw new Error('Profile site.title must be nonempty text');
191
201
  if (profile.site.indexing !== undefined && typeof profile.site.indexing !== 'boolean')
@@ -221,11 +231,31 @@ export async function resolveDeploymentProfile(settings, config, declaringFile,
221
231
  throw new Error('Profile asset must stay within the profile directory');
222
232
  // Explicit assets only. Symlinks must not introduce an undeclared capture root.
223
233
  let current = target;
234
+ const ancestry = [];
224
235
  while (current !== path.dirname(file)) {
225
- if ((await lstat(current)).isSymbolicLink())
226
- throw new Error('Profile assets must not use symlinks');
236
+ ancestry.unshift(current);
227
237
  current = path.dirname(current);
228
238
  }
239
+ for (const entry of ancestry) {
240
+ let info;
241
+ try {
242
+ info = await lstat(entry);
243
+ }
244
+ catch (error) {
245
+ // Every existing ancestor has passed the containment/symlink check.
246
+ // Watch only this declared target so creating it can repair a preview.
247
+ if (error.code === 'ENOENT')
248
+ onDependency?.(target);
249
+ throw error;
250
+ }
251
+ if (info.isSymbolicLink())
252
+ throw new Error('Profile assets must not use symlinks');
253
+ if (entry !== target && !info.isDirectory()) {
254
+ onDependency?.(target);
255
+ throw new Error('Profile asset parents must be directories');
256
+ }
257
+ }
258
+ onDependency?.(target);
229
259
  if (!(await lstat(target)).isFile())
230
260
  throw new Error(`Profile ${setting} must be a regular file`);
231
261
  assetFiles.push(target);
@@ -257,13 +287,13 @@ export async function resolveDeploymentProfile(settings, config, declaringFile,
257
287
  keys(profile.publications, ['enabled'], 'Profile publications');
258
288
  const enabled = profile.publications.enabled;
259
289
  const language = defaultLanguage(config);
260
- const coordinate = (value) => JSON.stringify([value.channel, value.version, value.language ?? language]);
290
+ const coordinate = (value) => publicationKey(resolvePublication(config.publications, value, language));
261
291
  if (!Array.isArray(enabled) || !enabled.length)
262
292
  throw new Error('Profile publications.enabled must be a nonempty subset of shared publications.enabled');
263
293
  const selected = new Set();
264
294
  for (const variant of enabled) {
265
- keys(variant, ['channel', 'version', 'language'], 'Profile publication');
266
- if (typeof variant.channel !== 'string' || typeof variant.version !== 'string' || (variant.language !== undefined && typeof variant.language !== 'string') || !config.publications?.enabled?.some((entry) => coordinate(entry) === coordinate(variant)))
295
+ keys(variant, ['product', 'channel', 'version', 'language'], 'Profile publication');
296
+ if (typeof variant.channel !== 'string' || (variant.version !== undefined && typeof variant.version !== 'string') || (variant.product !== undefined && typeof variant.product !== 'string') || (variant.language !== undefined && typeof variant.language !== 'string') || !config.publications?.enabled?.some((entry) => coordinate(entry) === coordinate(variant)))
267
297
  throw new Error('Profile publication is not enabled by the shared configuration');
268
298
  const key = coordinate(variant);
269
299
  if (selected.has(key))
package/dist/dev.d.ts CHANGED
@@ -1,2 +1,4 @@
1
1
  import type { Server } from 'node:http';
2
- export declare function startDev(configFile: string, outputDirectory: string, host?: string, port?: number): Promise<Server>;
2
+ export declare function startDev(configFile: string, outputDirectory: string, host?: string, port?: number, options?: {
3
+ profile?: string;
4
+ }): Promise<Server>;
package/dist/dev.js CHANGED
@@ -1,8 +1,18 @@
1
- import { watch } from 'node:fs';
1
+ import { statSync, watch } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { compile } from './compiler.js';
4
4
  import { serveSite } from './server.js';
5
- export async function startDev(configFile, outputDirectory, host = '127.0.0.1', port = 8765) {
5
+ import { homeUrl } from './negotiation.js';
6
+ function dependencyStamp(file) {
7
+ try {
8
+ const info = statSync(file, { bigint: true });
9
+ return `${info.dev}:${info.ino}:${info.size}:${info.mtimeNs}:${info.ctimeNs}:${info.mode}`;
10
+ }
11
+ catch (error) {
12
+ return `missing:${error.code ?? 'unknown'}`;
13
+ }
14
+ }
15
+ export async function startDev(configFile, outputDirectory, host = '127.0.0.1', port = 8765, options = {}) {
6
16
  const config = path.resolve(configFile);
7
17
  const root = path.dirname(config);
8
18
  const output = path.resolve(outputDirectory);
@@ -10,29 +20,63 @@ export async function startDev(configFile, outputDirectory, host = '127.0.0.1',
10
20
  const stagingPrefix = `${output}.staging-`;
11
21
  const ignored = new Set(['.git', '.shoalrun', 'node_modules']);
12
22
  const clients = new Set();
13
- const initial = await compile(config, output);
14
- const server = await serveSite(output, host, port, clients);
23
+ const profile = options.profile ? path.resolve(options.profile) : undefined;
24
+ const initialStamps = new Map();
25
+ const initial = await compile(config, output, {}, { profile, onDependency: file => {
26
+ const resolved = path.resolve(file);
27
+ if (!initialStamps.has(resolved))
28
+ initialStamps.set(resolved, dependencyStamp(resolved));
29
+ } });
30
+ let successfulDependencies = initial.dependencies;
31
+ const preview = { ...(profile ? { profile: path.basename(profile) } : {}), buildId: initial.buildId, profileDigest: initial.profileSelection?.profileDigest };
32
+ const server = await serveSite(output, host, port, clients, { preview });
15
33
  process.stdout.write(`Preview: http://${host}:${server.address().port}/\n`);
16
34
  let timer;
17
35
  let dirty = false;
18
36
  let running = false;
37
+ let closed = false;
19
38
  const external = new Map();
39
+ const dependencyStamps = new Map();
20
40
  const changed = () => {
41
+ if (closed)
42
+ return;
21
43
  dirty = true;
22
44
  if (timer)
23
45
  clearTimeout(timer);
24
46
  timer = setTimeout(() => { void rebuild(); }, 180);
25
47
  };
26
48
  const refreshExternal = (dependencies) => {
49
+ if (closed)
50
+ return;
27
51
  const needed = new Map();
28
- for (const dependency of dependencies) {
52
+ const files = new Set();
53
+ for (const dependency of [...dependencies, ...(profile ? [profile] : [])]) {
29
54
  const file = path.resolve(dependency);
55
+ files.add(file);
56
+ if (!dependencyStamps.has(file))
57
+ dependencyStamps.set(file, initialStamps.get(file) ?? dependencyStamp(file));
30
58
  if (file === root || (file.startsWith(`${root}${path.sep}`) && !path.relative(root, file).split(path.sep).some(part => ignored.has(part))))
31
59
  continue;
32
- const parent = path.dirname(file);
60
+ let parent = path.dirname(file);
61
+ // A missing asset may also have missing parent directories. Watch its
62
+ // nearest existing directory, filtered to the next declared component.
63
+ while (true) {
64
+ try {
65
+ if (statSync(parent).isDirectory())
66
+ break;
67
+ }
68
+ catch (error) {
69
+ if (!['ENOENT', 'ENOTDIR'].includes(error.code ?? ''))
70
+ throw error;
71
+ }
72
+ const next = path.dirname(parent);
73
+ if (next === parent)
74
+ throw new Error(`No watchable parent for ${file}`);
75
+ parent = next;
76
+ }
33
77
  if (!needed.has(parent))
34
78
  needed.set(parent, new Set());
35
- needed.get(parent).add(path.basename(file));
79
+ needed.get(parent).add(path.relative(parent, file).split(path.sep)[0]);
36
80
  }
37
81
  for (const [directory, value] of external)
38
82
  if (!needed.has(directory)) {
@@ -46,27 +90,50 @@ export async function startDev(configFile, outputDirectory, host = '127.0.0.1',
46
90
  continue;
47
91
  }
48
92
  const entry = { names, watcher: undefined };
49
- entry.watcher = watch(directory, (_event, filename) => { if (!filename || entry.names.has(filename.toString()))
50
- changed(); });
93
+ entry.watcher = watch(directory, (_event, filename) => {
94
+ if (!filename || entry.names.has(filename.toString())) {
95
+ const file = filename ? path.resolve(directory, filename.toString()) : undefined;
96
+ if (file && dependencyStamps.has(file))
97
+ dependencyStamps.set(file, dependencyStamp(file));
98
+ changed();
99
+ }
100
+ });
51
101
  entry.watcher.on('error', error => process.stderr.write(`Watch failed: ${error.message}\n`));
52
102
  external.set(directory, entry);
53
103
  }
104
+ for (const file of dependencyStamps.keys())
105
+ if (!files.has(file))
106
+ dependencyStamps.delete(file);
107
+ initialStamps.clear();
54
108
  };
55
109
  const rebuild = async () => {
56
110
  if (running)
57
111
  return;
58
112
  running = true;
59
- while (dirty) {
113
+ while (dirty && !closed) {
60
114
  dirty = false;
115
+ const discovered = new Set();
61
116
  try {
62
- const manifest = await compile(config, output);
117
+ const manifest = await compile(config, output, {}, { profile, onDependency: file => discovered.add(file) });
118
+ preview.buildId = manifest.buildId;
119
+ preview.profileDigest = manifest.profileSelection?.profileDigest;
120
+ delete preview.error;
121
+ successfulDependencies = manifest.dependencies;
63
122
  refreshExternal(manifest.dependencies);
64
123
  process.stdout.write(`Built ${manifest.documents.length} documents\n`);
124
+ const update = { routes: manifest.documents.map(document => document.url), home: homeUrl(manifest.documents) };
65
125
  for (const client of clients)
66
- client.write('event: built\ndata: {}\n\n');
126
+ client.write(`event: built\ndata: ${JSON.stringify(update)}\n\n`);
67
127
  }
68
128
  catch (error) {
69
129
  const message = error instanceof Error ? error.message : String(error);
130
+ preview.error = message;
131
+ try {
132
+ refreshExternal([...successfulDependencies, ...discovered]);
133
+ }
134
+ catch (watchError) {
135
+ process.stderr.write(`Watch failed: ${watchError instanceof Error ? watchError.message : String(watchError)}\n`);
136
+ }
70
137
  process.stderr.write(`Build failed: ${message}\n`);
71
138
  for (const client of clients)
72
139
  client.write(`event: failed\ndata: ${JSON.stringify({ message })}\n\n`);
@@ -84,6 +151,8 @@ export async function startDev(configFile, outputDirectory, host = '127.0.0.1',
84
151
  const file = path.resolve(root, filename.toString());
85
152
  if (file === output || file === `${output}.shoalrun.lock` || file.startsWith(outputPrefix) || file.startsWith(stagingPrefix))
86
153
  return;
154
+ if (dependencyStamps.has(file))
155
+ dependencyStamps.set(file, dependencyStamp(file));
87
156
  }
88
157
  changed();
89
158
  });
@@ -96,8 +165,24 @@ export async function startDev(configFile, outputDirectory, host = '127.0.0.1',
96
165
  throw error;
97
166
  }
98
167
  watcher.on('error', error => process.stderr.write(`Watch failed: ${error.message}\n`));
168
+ // Native directory notifications can be coalesced or lost, especially just
169
+ // after registration. Poll only the exact declared build dependencies as
170
+ // a fallback; seed their stamps synchronously so the first edit is observed.
171
+ const polling = setInterval(() => {
172
+ if (closed)
173
+ return;
174
+ for (const [file, previous] of dependencyStamps) {
175
+ const current = dependencyStamp(file);
176
+ if (current !== previous) {
177
+ dependencyStamps.set(file, current);
178
+ changed();
179
+ }
180
+ }
181
+ }, 500);
182
+ polling.unref();
99
183
  const close = server.close.bind(server);
100
184
  server.close = ((callback) => {
185
+ closed = true;
101
186
  for (const client of clients)
102
187
  client.end();
103
188
  return close(callback);
@@ -106,6 +191,8 @@ export async function startDev(configFile, outputDirectory, host = '127.0.0.1',
106
191
  watcher.close();
107
192
  for (const entry of external.values())
108
193
  entry.watcher.close();
194
+ dependencyStamps.clear();
195
+ clearInterval(polling);
109
196
  if (timer)
110
197
  clearTimeout(timer);
111
198
  });
@@ -1,3 +1,4 @@
1
+ import { documentKey } from './publication-identity.js';
1
2
  import { validateAuthoringGuidance } from './authoring-guidance.js';
2
3
  import { createHash, randomUUID } from 'node:crypto';
3
4
  import { chmod, cp, link, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, writeFile } from 'node:fs/promises';
@@ -350,7 +351,7 @@ export async function docsApply(planFile, configFile, checkOnly, options = {}) {
350
351
  if (!rendered.documents.some(doc => doc.id === id))
351
352
  throw new Error(`Candidate excluded from rendering: ${id}`);
352
353
  }
353
- const key = (doc) => `${doc.id}|${doc.variant.channel}|${doc.variant.version}|${doc.variant.language}`;
354
+ const key = (doc) => documentKey(doc.id, doc.variant);
354
355
  const oldDocs = new Map(before?.documents.map(doc => [key(doc), doc]) ?? []);
355
356
  const newDocs = new Map(result.documents.map(doc => [key(doc), doc]));
356
357
  const affected = [...new Set([...oldDocs.keys(), ...newDocs.keys()])].filter(id => {
@@ -20,7 +20,7 @@ export function parseDocsReadOptions(args, mcp = false) {
20
20
  continue;
21
21
  }
22
22
  const value = args[++i];
23
- if (!(mcp ? ['--site'] : ['--site', '--max-tokens', '--limit', '--channel', '--version', '--language']).includes(flag) || !value || value.startsWith('--'))
23
+ if (!(mcp ? ['--site'] : ['--site', '--max-tokens', '--limit', '--product', '--channel', '--version', '--language']).includes(flag) || !value || value.startsWith('--'))
24
24
  throw new DocumentationError('invalid_input', `Unknown option or missing value for ${flag}`);
25
25
  if (flag === '--site')
26
26
  directory = path.resolve(value);
@@ -40,7 +40,7 @@ export async function runDocsReadCommand(command, args) {
40
40
  const parsed = parseDocsReadOptions(args);
41
41
  json = json || parsed.json;
42
42
  if (!parsed.positional.length || command !== 'search' && parsed.positional.length !== (command === 'section' ? 2 : 1) || command !== 'search' && parsed.options.limit !== undefined)
43
- throw new DocumentationError('invalid_input', `Usage: shoalrun docs ${command} <${command === 'search' ? 'query' : command === 'section' ? 'document-id> <section-id' : 'document-id'}> [--site DIRECTORY] [--json] [--max-tokens N] [--channel C --version V --language L]${command === 'search' ? ' [--limit N]' : ''}`);
43
+ throw new DocumentationError('invalid_input', `Usage: shoalrun docs ${command} <${command === 'search' ? 'query' : command === 'section' ? 'document-id> <section-id' : 'document-id'}> [--site DIRECTORY] [--json] [--max-tokens N] [--product P --channel C --version V --language L]${command === 'search' ? ' [--limit N]' : ''}`);
44
44
  const result = command === 'search'
45
45
  ? await searchDocumentation(parsed.directory, parsed.positional.join(' '), parsed.options)
46
46
  : command === 'outline' ? await getDocumentationOutline(parsed.directory, parsed.positional[0], parsed.options)
@@ -14,6 +14,7 @@ export type EvalTasks = {
14
14
  tasks: EvalTask[];
15
15
  };
16
16
  type Publication = {
17
+ product?: string;
17
18
  channel: string;
18
19
  version: string;
19
20
  language: string;
package/dist/docs-eval.js CHANGED
@@ -89,8 +89,8 @@ export function parseEvalReport(value) {
89
89
  throw new Error(`${where} requires status pass/fail/skipped, a text answer, citations, and criteria`);
90
90
  const citations = result.citations.map((value, j) => {
91
91
  const cite = mapping(value, `${where}.citations[${j}]`, ['id', 'publication']);
92
- const publication = mapping(cite.publication, `${where}.citations[${j}].publication`, ['channel', 'version', 'language']);
93
- return { id: text(cite.id, `${where}.citations[${j}].id`), publication: { channel: text(publication.channel, 'citation.channel'), version: text(publication.version, 'citation.version'), language: text(publication.language, 'citation.language') } };
92
+ const publication = mapping(cite.publication, `${where}.citations[${j}].publication`, ['product', 'channel', 'version', 'language']);
93
+ return { id: text(cite.id, `${where}.citations[${j}].id`), publication: { ...(publication.product === undefined ? {} : { product: text(publication.product, 'citation.product') }), channel: text(publication.channel, 'citation.channel'), version: text(publication.version, 'citation.version'), language: text(publication.language, 'citation.language') } };
94
94
  });
95
95
  const criteria = unique(result.criteria.map((value, j) => {
96
96
  const judgment = mapping(value, `${where}.criteria[${j}]`, ['id', 'status', 'reason']);
@@ -1,6 +1,7 @@
1
1
  import { type McpAnalyticsEvent } from './mcp-analytics.js';
2
2
  import { McpServer } from '@modelcontextprotocol/server';
3
3
  export declare function createDocsMcpServer(directory?: string, publication?: {
4
+ product?: string;
4
5
  channel: string;
5
6
  version: string;
6
7
  language: string;