@shoalrun/cli 1.0.0 → 1.1.0
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.
- package/CHANGELOG.md +19 -0
- package/CODE-REFERENCES.md +19 -0
- package/README.md +13 -4
- package/adapters/typescript/README.md +27 -0
- package/adapters/typescript/shoalrun-reference.mjs +260 -0
- package/agent-docs/.well-known/shoalrun/navigation/project-updates-50f26fe22670.txt +3 -1
- package/agent-docs/SNAPSHOT.json +5 -5
- package/agent-docs/api-docs/code-reference-settings.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/catalog-settings.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/complete-reference-page.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/converter-snapshot.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/descriptions-type-links-and-source-links.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/html-markdown-and-agents.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/metadata-and-selection.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/publication-sources.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/python-adapter-limits.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/related-reading.md +2 -2
- package/agent-docs/api-docs/code-reference-settings.sections/symbol-fields.md +2 -2
- package/agent-docs/api-docs/code-references.md +9 -1
- package/agent-docs/api-docs/code-references.sections/a-real-typescript-example.md +38 -0
- package/agent-docs/api-docs/code-references.sections/add-python-source.md +56 -0
- package/agent-docs/api-docs/code-references.sections/before-you-start.md +40 -0
- package/agent-docs/api-docs/code-references.sections/build-and-verify.md +47 -0
- package/agent-docs/api-docs/code-references.sections/choose-the-reading-layout.md +46 -0
- package/agent-docs/api-docs/code-references.sections/extract-and-validate-a-snapshot.md +52 -0
- package/agent-docs/api-docs/code-references.sections/html-markdown-and-agents.md +42 -0
- package/agent-docs/api-docs/code-references.sections/register-the-catalog-and-navigation.md +58 -0
- package/agent-docs/api-docs/code-references.sections/related-reading.md +40 -0
- package/agent-docs/api-docs/code-references.sections/versions-profiles-and-delivery.md +40 -0
- package/agent-docs/api-docs/typescript-references.md +93 -0
- package/agent-docs/author/components/for-facet.md +127 -0
- package/agent-docs/author/components/only.md +3 -1
- package/agent-docs/author/components.md +2 -1
- package/agent-docs/author/reader-views.md +2 -2
- package/agent-docs/author/reader-views.sections/configure-the-choices.md +2 -2
- package/agent-docs/author/reader-views.sections/connect-your-own-control.md +2 -2
- package/agent-docs/author/reader-views.sections/how-it-works-for-agents.md +2 -2
- package/agent-docs/author/reader-views.sections/mark-pages.md +2 -2
- package/agent-docs/author/reader-views.sections/mark-sections-and-add-an-entry-choice.md +2 -2
- package/agent-docs/author/reader-views.sections/place-filter-controls.md +2 -2
- package/agent-docs/author/reader-views.sections/try-the-controls-here.md +2 -2
- package/agent-docs/changelog/facet-typescript.md +54 -0
- package/agent-docs/changelog.md +8 -0
- package/agent-docs/config/examples.md +2 -2
- package/agent-docs/config/examples.sections/feature-showcase.md +2 -2
- package/agent-docs/config/examples.sections/minimal-site.md +1 -1
- package/agent-docs/config/examples.sections/multilingual-help-center.md +1 -1
- package/agent-docs/config/examples.sections/parcel-api-documentation.md +1 -1
- package/agent-docs/config/examples.sections/related-reading.md +1 -1
- package/agent-docs/config/examples.sections/shared-company-preset.md +1 -1
- package/agent-docs/config/outputs.md +12 -12
- package/agent-docs/config/outputs.sections/exports.md +12 -12
- package/agent-docs/config/outputs.sections/metadata.md +1 -1
- package/agent-docs/config/outputs.sections/pdf-output.md +1 -1
- package/agent-docs/config/outputs.sections/related-reading.md +1 -1
- package/agent-docs/config/site.md +17 -17
- package/agent-docs/config/site.sections/related-reading.md +1 -1
- package/agent-docs/config/site.sections/theme.md +1 -1
- package/agent-docs/configuration.md +1 -1
- package/agent-docs/configuration.sections/start-with-one-working-file.md +1 -1
- package/agent-docs/content-delivery/api.md +10 -2
- package/agent-docs/content-delivery/api.sections/errors.md +52 -0
- package/agent-docs/content-delivery/api.sections/generated-typescript-reference.md +36 -0
- package/agent-docs/content-delivery/api.sections/html-markdown-and-agents.md +36 -0
- package/agent-docs/content-delivery/api.sections/mount-html.md +42 -0
- package/agent-docs/content-delivery/api.sections/open-a-rest-source.md +55 -0
- package/agent-docs/content-delivery/api.sections/open-a-source.md +51 -0
- package/agent-docs/content-delivery/api.sections/read-a-snapshot.md +55 -0
- package/agent-docs/content-delivery/api.sections/related-reading.md +42 -0
- package/agent-docs/content-delivery/api.sections/validate-a-manifest.md +40 -0
- package/agent-docs/content-delivery/client.md +9 -1
- package/agent-docs/content-delivery/sdk/all.md +1772 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-exportedid.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-id.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor-title.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentanchor.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentasset-mediatype.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentasset.md +40 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliveryerror-code.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliveryerror.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-manifestbytes.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-resourcebytes.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits-resources.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentdeliverylimits.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contenterrorcode.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-bytes.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-digest.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile-path.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentfile.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentformat.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-asset.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-fragment.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-href.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-kind.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-query.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink-ref.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentlink.md +52 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-assets.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-diagnostics.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-digest.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-files.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-kind.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-publicbase.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-resources.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-review.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmanifest.md +68 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-anchors.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-links.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount-unmount.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentmount.md +49 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-channel.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-language.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-product.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication-version.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentpublication.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentref.md +43 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrefkey.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation-anchors.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation-links.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrepresentation.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-assets.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-canonicalurl.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-externaldependencies.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-ref.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-representations.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-source.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-summary.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-title.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource-type.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresource.md +65 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresourcekey.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry-resource.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestentry.md +42 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterror-error.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterror.md +43 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresterrorcode.md +32 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-resources.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-revision.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestlist.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-key.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-publication.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-resource.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-revision.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource-schemaversion.md +34 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentrestresource.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-content.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-format.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-representation.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-resource.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentresult.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-dispose.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-get.md +45 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-list.md +38 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-contentsnapshot.md +47 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-fetch.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-limits.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-manifesturl.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions-signal.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-manifestcontentsourceoptions.md +46 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-mountcontent.md +48 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-openmanifestcontentsource.md +54 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-openrestcontentsource.md +44 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-baseurl.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-fetch.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-limits.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-publication.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-revision.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions-signal.md +36 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-restcontentsourceoptions.md +50 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content-validatecontentmanifest.md +45 -0
- package/agent-docs/content-delivery/sdk/all.sections/shoalrun-content.md +65 -0
- package/agent-docs/content-delivery/sdk/content-anchor/exported-id.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor/id.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor/title.md +25 -0
- package/agent-docs/content-delivery/sdk/content-anchor.md +71 -0
- package/agent-docs/content-delivery/sdk/content-asset/media-type.md +25 -0
- package/agent-docs/content-delivery/sdk/content-asset.md +43 -0
- package/agent-docs/content-delivery/sdk/content-delivery-error/code.md +25 -0
- package/agent-docs/content-delivery/sdk/content-delivery-error.md +53 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/manifest-bytes.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/resource-bytes.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits/resources.md +27 -0
- package/agent-docs/content-delivery/sdk/content-delivery-limits.md +77 -0
- package/agent-docs/content-delivery/sdk/content-error-code.md +23 -0
- package/agent-docs/content-delivery/sdk/content-file/bytes.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file/digest.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file/path.md +25 -0
- package/agent-docs/content-delivery/sdk/content-file.md +71 -0
- package/agent-docs/content-delivery/sdk/content-format.md +23 -0
- package/agent-docs/content-delivery/sdk/content-link/asset.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/fragment.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/href.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/kind.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/query.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link/ref.md +25 -0
- package/agent-docs/content-delivery/sdk/content-link.md +127 -0
- package/agent-docs/content-delivery/sdk/content-manifest/assets.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/diagnostics.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/digest.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/files.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/kind.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/public-base.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/resources.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/review.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-manifest.md +179 -0
- package/agent-docs/content-delivery/sdk/content-mount/anchors.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount/links.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount/unmount.md +27 -0
- package/agent-docs/content-delivery/sdk/content-mount.md +82 -0
- package/agent-docs/content-delivery/sdk/content-publication/channel.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/language.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/product.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication/version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-publication.md +85 -0
- package/agent-docs/content-delivery/sdk/content-ref-key.md +34 -0
- package/agent-docs/content-delivery/sdk/content-ref.md +40 -0
- package/agent-docs/content-delivery/sdk/content-representation/anchors.md +25 -0
- package/agent-docs/content-delivery/sdk/content-representation/links.md +25 -0
- package/agent-docs/content-delivery/sdk/content-representation.md +57 -0
- package/agent-docs/content-delivery/sdk/content-resource/assets.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/canonical-url.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/external-dependencies.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/ref.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/representations.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/source.md +25 -0
- package/agent-docs/content-delivery/sdk/content-resource/summary.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/title.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource/type.md +27 -0
- package/agent-docs/content-delivery/sdk/content-resource-key.md +34 -0
- package/agent-docs/content-delivery/sdk/content-resource.md +192 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry/resource.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-entry.md +57 -0
- package/agent-docs/content-delivery/sdk/content-rest-error/error.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-error-code.md +23 -0
- package/agent-docs/content-delivery/sdk/content-rest-error.md +46 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/resources.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/revision.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-list.md +85 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/key.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/publication.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/resource.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/revision.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource/schema-version.md +25 -0
- package/agent-docs/content-delivery/sdk/content-rest-resource.md +99 -0
- package/agent-docs/content-delivery/sdk/content-result/content.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/format.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/representation.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/resource.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/content-result.md +114 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/dispose.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/get.md +36 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/list.md +29 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/content-snapshot.md +123 -0
- package/agent-docs/content-delivery/sdk/exports.md +742 -0
- package/agent-docs/content-delivery/sdk/exports.sections/functions.md +30 -0
- package/agent-docs/content-delivery/sdk/exports.sections/members.md +47 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentanchor.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentasset.md +37 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentdeliveryerror.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentdeliverylimits.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contenterrorcode.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentfile.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentformat.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentlink.md +49 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentmanifest.md +65 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentmount.md +46 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentpublication.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentref.md +40 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrefkey.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrepresentation.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresource.md +62 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresourcekey.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestentry.md +39 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresterror.md +40 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresterrorcode.md +29 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestlist.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentrestresource.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentresult.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-contentsnapshot.md +44 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-manifestcontentsourceoptions.md +43 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-mountcontent.md +45 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-openmanifestcontentsource.md +51 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-openrestcontentsource.md +41 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-restcontentsourceoptions.md +47 -0
- package/agent-docs/content-delivery/sdk/exports.sections/shoalrun-content-validatecontentmanifest.md +42 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/fetch.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/limits.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/manifest-url.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options/signal.md +27 -0
- package/agent-docs/content-delivery/sdk/manifest-content-source-options.md +93 -0
- package/agent-docs/content-delivery/sdk/mount-content.md +46 -0
- package/agent-docs/content-delivery/sdk/open-manifest-content-source.md +51 -0
- package/agent-docs/content-delivery/sdk/open-rest-content-source.md +39 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/base-url.md +28 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/fetch.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/limits.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/publication.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/revision.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options/signal.md +27 -0
- package/agent-docs/content-delivery/sdk/rest-content-source-options.md +125 -0
- package/agent-docs/content-delivery/sdk/validate-content-manifest.md +38 -0
- package/agent-docs/contribute/agent-skills.md +33 -6
- package/agent-docs/documents.json +7094 -308
- package/agent-docs/features.md +18 -17
- package/agent-docs/provenance.json +6 -6
- package/agent-docs/publish/content-export.md +3 -1
- package/agent-docs/publish/content-export.sections/assets-downloads-and-notices.md +1 -1
- package/agent-docs/publish/content-export.sections/check-the-result.md +1 -1
- package/agent-docs/publish/content-export.sections/inspect-the-manifest.md +1 -1
- package/agent-docs/publish/content-export.sections/prerequisites.md +1 -1
- package/agent-docs/publish/content-export.sections/related-reading.md +1 -1
- package/agent-docs/publish/content-export.sections/review-exported-api-material.md +1 -1
- package/agent-docs/publish/content-export.sections/try-the-help-drawer-example.md +1 -1
- package/agent-docs/publish/content-export.sections/what-the-representations-retain.md +1 -1
- package/agent-docs/publish/pdf.md +2 -2
- package/agent-docs/publish/pdf.sections/apply-print-styling.md +1 -1
- package/agent-docs/publish/pdf.sections/check-the-result.md +1 -1
- package/agent-docs/publish/pdf.sections/export-a-page-or-publication.md +2 -2
- package/agent-docs/publish/pdf.sections/html-markdown-and-agents.md +1 -1
- package/agent-docs/publish/pdf.sections/offer-browser-page-printing.md +1 -1
- package/agent-docs/publish/pdf.sections/offer-direct-downloads-through-a-node-server.md +1 -1
- package/agent-docs/publish/pdf.sections/prerequisites.md +1 -1
- package/agent-docs/publish/pdf.sections/publish-an-optional-manual-download.md +1 -1
- package/agent-docs/publish/single-source-sites.md +26 -2
- package/agent-docs/publish/single-source-sites.sections/build-and-check-each-output.md +49 -0
- package/agent-docs/publish/single-source-sites.sections/html-markdown-and-agents.md +33 -0
- package/agent-docs/publish/single-source-sites.sections/include-additional-sections-in-a-build.md +47 -0
- package/agent-docs/publish/single-source-sites.sections/related-reading.md +43 -0
- package/agent-docs/publish/single-source-sites.sections/select-the-pages-for-each-site.md +74 -0
- package/agent-docs/publish/single-source-sites.sections/share-the-base-configuration.md +93 -0
- package/agent-docs/reference/agent-skills.md +2 -2
- package/agent-docs/search-index.json +1 -1
- package/agent-docs/start.md +1 -1
- package/agent-docs/start.sections/start-your-own-project.md +1 -1
- package/assets/search-lexical.js +15 -4
- package/dist/code-reference-model.d.ts +4 -4
- package/dist/compiler.d.ts +8 -0
- package/dist/compiler.js +10 -4
- package/dist/component-names.js +1 -1
- package/dist/component-transform.js +14 -22
- package/dist/conditional-tree.d.ts +2 -0
- package/dist/conditional-tree.js +14 -0
- package/dist/content-delivery-contract.d.ts +39 -0
- package/dist/content-delivery-contract.js +2 -0
- package/dist/content-delivery-validation.d.ts +6 -0
- package/dist/content-delivery-validation.js +6 -0
- package/dist/content-delivery.d.ts +19 -1
- package/dist/content-delivery.js +10 -1
- package/dist/content-export-command.d.ts +42 -3
- package/dist/content-export.d.ts +42 -3
- package/dist/content-export.js +15 -6
- package/dist/content-filter.d.ts +2 -0
- package/dist/content-filter.js +4 -0
- package/dist/content-mount.d.ts +12 -1
- package/dist/content-mount.js +8 -1
- package/dist/content-rest-client.d.ts +11 -1
- package/dist/content-rest-client.js +4 -1
- package/dist/content-rest-contract.d.ts +5 -0
- package/dist/content-source.d.ts +1 -0
- package/dist/content-workspace.d.ts +4 -1
- package/dist/content-workspace.js +5 -2
- package/dist/deployment-profile.d.ts +3 -1
- package/dist/deployment-profile.js +18 -19
- package/dist/palettes.d.ts +1 -1
- package/dist/publication-manifest.js +1 -1
- package/dist/representation-tree.js +8 -2
- package/dist/search-query.js +13 -6
- package/dist/section-selection.d.ts +29 -0
- package/dist/section-selection.js +92 -0
- package/dist/snippets.d.ts +1 -0
- package/example-configs/facet-sections/README.md +37 -0
- package/example-configs/facet-sections/base.yaml +29 -0
- package/example-configs/facet-sections/content/billing.mdx +25 -0
- package/example-configs/facet-sections/customer.config.yaml +4 -0
- package/example-configs/facet-sections/docs.config.yaml +3 -0
- package/example-configs/faceted-sites/README.md +4 -2
- package/package.json +2 -1
- package/skills/shoalrun-author/SKILL.md +13 -0
- package/skills/shoalrun-author/references/code-api-references.md +5 -1
- package/skills/shoalrun-author/references/facet-selection.md +48 -0
- package/skills/shoalrun-brand/SKILL.md +9 -0
- package/skills/shoalrun-component-author/SKILL.md +9 -0
- package/skills/shoalrun-pdf/SKILL.md +9 -0
- package/skills/shoalrun-recipes/SKILL.md +9 -0
- package/skills/shoalrun-setup/SKILL.md +9 -0
- package/skills/shoalrun-walkthrough/SKILL.md +9 -0
package/dist/content-export.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { createSectionSelection, pruneSelectedTree, sectionSelectionReport, writeSectionSelectionReport } from './section-selection.js';
|
|
1
2
|
import { documentKey, publicationKey, samePublication } from './publication-identity.js';
|
|
2
|
-
import {
|
|
3
|
+
import { profileSelection } from './deployment-profile.js';
|
|
3
4
|
import { readFile, realpath } from 'node:fs/promises';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
@@ -121,7 +122,8 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
121
122
|
const providerSetting = configField(config.metadata, 'provider');
|
|
122
123
|
const metadataProvider = await loadMetadataProvider(providerSetting, providerSetting ? explainSegments(loaded, ['metadata', 'provider', 'module']).source.file : configFile);
|
|
123
124
|
const metadataDependencies = new Set();
|
|
124
|
-
const
|
|
125
|
+
const sectionSelection = createSectionSelection(readerFilters, selection, publications);
|
|
126
|
+
const workspace = await prepareContentWorkspace({ base, basePath, config, loaded, variants: [publication], language, readerFilters, metadataProvider, metadataDependencies, sectionSelection, allowRouteCollisions: true });
|
|
125
127
|
const { docs: eligible, apiPlan, snippets, sourceForOperation } = workspace;
|
|
126
128
|
const ids = new Set(target.resources ? target.resources.filter(item => item.kind !== 'snippet').map(item => item.documentId) : target.documents);
|
|
127
129
|
for (const id of ids) {
|
|
@@ -180,7 +182,7 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
180
182
|
throw new Error(`Unknown export snippet ${selection.snippetId}`);
|
|
181
183
|
// This is an explicit isolated context. It has no containing page, operations,
|
|
182
184
|
// relationships, page variables, or inherited publication/access metadata.
|
|
183
|
-
const snippetDocument = { featureContext: loaded.deployment?.context, file: definition.file, body: '', tree: root([]), variant: publication,
|
|
185
|
+
const snippetDocument = { sectionSelection, featureContext: loaded.deployment?.context, file: definition.file, body: '', tree: root([]), variant: publication,
|
|
184
186
|
route: `/__content_snippets/${encodeURIComponent(selection.id)}`, markdownRoute: '',
|
|
185
187
|
frontmatter: { id: selection.id, title: selection.title, summary: selection.summary, type: 'snippet', slug: '/', access: { policy: 'public' } } };
|
|
186
188
|
const checkSnippet = (id, seen = new Set()) => {
|
|
@@ -190,7 +192,7 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
190
192
|
const source = snippets.get(id);
|
|
191
193
|
if (!source)
|
|
192
194
|
throw new Error(`Unknown snippet ${id}`);
|
|
193
|
-
visitTree(
|
|
195
|
+
visitTree(pruneSelectedTree(source.tree, snippetDocument, source.file, false), node => {
|
|
194
196
|
if (['RelatedReading', 'DocCard', 'DocCards', 'DocCollection', 'CookbookChooser', 'ApiExample', 'ApiSchema', 'FrontmatterReference', 'Anchor'].includes(node.name))
|
|
195
197
|
throw new Error(`Snippet instance ${selection.id}: <${node.name}> needs page context`);
|
|
196
198
|
if (node.name === 'Snippet') {
|
|
@@ -316,6 +318,11 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
316
318
|
const key = `${sourceKeyFor(destination)}:${format}`;
|
|
317
319
|
if (canonicalAnchors.has(key))
|
|
318
320
|
return canonicalAnchors.get(key);
|
|
321
|
+
// An export-selected tree cannot prove anchors in a differently selected website.
|
|
322
|
+
// Refuse the fragment rather than silently publish a broken canonical link.
|
|
323
|
+
const normalizeSelection = (value) => JSON.stringify(Object.entries(value ?? {}).sort(([a], [b]) => compare(a, b)).map(([facet, choices]) => [facet, [...choices].sort(compare)]));
|
|
324
|
+
if (sectionSelection.hasConditions && normalizeSelection(selection) !== normalizeSelection(siteSelection))
|
|
325
|
+
throw new Error(`Cannot verify canonical anchor in ${destination.frontmatter.id} across different site and export contentFilter selections; include the target resource or use its page URL without a fragment`);
|
|
319
326
|
const source = sourceInventories.get(key);
|
|
320
327
|
if (!source || destination.endpoint)
|
|
321
328
|
throw new Error(`Cannot validate canonical fragments in ${destination.frontmatter.id}; select the target resource explicitly`);
|
|
@@ -553,7 +560,7 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
553
560
|
};
|
|
554
561
|
const input = { documents: printDocuments, title: selected.length === 1 ? selected[0].title : site.title, publication, assets: assets.artifacts, publicBase: target.publicBase, config: pdfConfig, configFile, assetRoots: [...roots, ...pdfInputs.map(file => path.dirname(file))] };
|
|
555
562
|
const preparedPdf = { input, manifest, inputs };
|
|
556
|
-
const common = { status: unreviewed.length ? 'needs-review' : 'ok', output: path.resolve(destination || base), publication, formats: target.formats, profileSelection: profileSelection(loaded.deployment), resources: records.length, documents: records.length, documentIds: selected.map(item => item.doc.frontmatter.id), comparison: { status: 'no-baseline', added: [], removed: [], diagnostics: [] }, assets: assets.records.size, apiReview: manifest.review.apis, diagnostics };
|
|
563
|
+
const common = { status: unreviewed.length ? 'needs-review' : 'ok', output: path.resolve(destination || base), publication, formats: target.formats, profileSelection: profileSelection(loaded.deployment), contentSelection: sectionSelectionReport(sectionSelection), resources: records.length, documents: records.length, documentIds: selected.map(item => item.doc.frontmatter.id), comparison: { status: 'no-baseline', added: [], removed: [], diagnostics: [] }, assets: assets.records.size, apiReview: manifest.review.apis, diagnostics };
|
|
557
564
|
if (options.preparePdfOnly)
|
|
558
565
|
return { ...common, digest: exportDigest(JSON.stringify(manifest)), preparedPdf };
|
|
559
566
|
checkOutputDirectory(destination, base, workspace.contentDir, inputs);
|
|
@@ -573,6 +580,7 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
573
580
|
const digest = exportDigest(JSON.stringify(payload));
|
|
574
581
|
pdfArtifacts.set('manifest.json', JSON.stringify({ ...payload, digest }, null, 2) + '\n');
|
|
575
582
|
await commitArtifacts(path.resolve(destination), pdfArtifacts, undefined, 'pdf');
|
|
583
|
+
await writeSectionSelectionReport(base, sectionSelection, { target: { kind: 'pdf', name: options.target ?? null, output: path.resolve(destination) }, buildId: digest, configDigest: loaded.digest, filterOrigin: target.contentFilter ? 'export.contentFilter' : 'site.contentFilter' });
|
|
576
584
|
return { ...common, digest, pdf: filename };
|
|
577
585
|
}
|
|
578
586
|
const manifest = { schemaVersion: publication.product === undefined ? 1 : 2, kind: 'shoalrun-content-export', publicBase: target.publicBase, publication,
|
|
@@ -599,7 +607,8 @@ export async function exportContent(configFile, destination, options = {}) {
|
|
|
599
607
|
throw new Error('Review candidate cannot overwrite an approved export; choose a separate review destination');
|
|
600
608
|
}
|
|
601
609
|
await commitArtifacts(path.resolve(destination), artifacts, undefined, 'export');
|
|
610
|
+
await writeSectionSelectionReport(base, sectionSelection, { target: { kind: 'export', name: options.target ?? null, output: path.resolve(destination) }, buildId: bundleDigest, configDigest: loaded.digest, filterOrigin: target.contentFilter ? 'export.contentFilter' : 'unfiltered' });
|
|
602
611
|
return { status: unreviewed.length ? 'needs-review' : 'ok', output: path.resolve(destination), publication, formats: target.formats,
|
|
603
|
-
profileSelection: profileSelection(loaded.deployment), resources: records.length, documents: records.filter(item => item.ref.kind === 'page').length, documentIds: records.flatMap(item => item.ref.kind === 'page' ? [item.ref.documentId] : []), comparison, assets: assets.records.size, digest: bundleDigest,
|
|
612
|
+
profileSelection: profileSelection(loaded.deployment), contentSelection: sectionSelectionReport(sectionSelection), resources: records.length, documents: records.filter(item => item.ref.kind === 'page').length, documentIds: records.flatMap(item => item.ref.kind === 'page' ? [item.ref.documentId] : []), comparison, assets: assets.records.size, digest: bundleDigest,
|
|
604
613
|
apiReview: reviews.map(row => ({ apiId: row.apiId, digest: row.digest })), diagnostics };
|
|
605
614
|
}
|
package/dist/content-filter.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ import { type ReaderFiltersConfig, type ReaderSelection } from './reader-filters
|
|
|
2
2
|
/** Build-time page selection; every selected facet must match at least one choice. */
|
|
3
3
|
export declare function validateContentFilter(value: unknown, facets?: ReaderFiltersConfig): ReaderSelection | undefined;
|
|
4
4
|
export declare function matchesContentFilter(marks: ReaderSelection | undefined, selection: ReaderSelection | undefined): boolean;
|
|
5
|
+
/** Section requirements narrow a selected page; unselected facets pass. */
|
|
6
|
+
export declare function matchesSectionContentFilter(requirements: ReaderSelection, selection: ReaderSelection | undefined): boolean;
|
package/dist/content-filter.js
CHANGED
|
@@ -14,3 +14,7 @@ export function validateContentFilter(value, facets) {
|
|
|
14
14
|
export function matchesContentFilter(marks, selection) {
|
|
15
15
|
return !selection || Object.entries(selection).every(([facet, choices]) => choices.some(choice => marks?.[facet]?.includes(choice)));
|
|
16
16
|
}
|
|
17
|
+
/** Section requirements narrow a selected page; unselected facets pass. */
|
|
18
|
+
export function matchesSectionContentFilter(requirements, selection) {
|
|
19
|
+
return Object.entries(requirements).every(([facet, choices]) => !selection?.[facet] || choices.some(choice => selection[facet].includes(choice)));
|
|
20
|
+
}
|
package/dist/content-mount.d.ts
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
1
|
import type { ContentAnchor, ContentLink, ContentResult } from './content-delivery-contract.js';
|
|
2
|
+
/** Handles and rewritten routing metadata for one mounted HTML instance. */
|
|
2
3
|
export type ContentMount = {
|
|
4
|
+
/** Anchors after instance-specific ID rewriting. */
|
|
3
5
|
anchors: readonly ContentAnchor[];
|
|
6
|
+
/** Typed links, including rewritten local fragments for this instance. */
|
|
4
7
|
links: readonly ContentLink[];
|
|
8
|
+
/** Remove nodes that still belong to this mount. */
|
|
5
9
|
unmount(): void;
|
|
6
10
|
};
|
|
7
|
-
/** Mount trusted compiler
|
|
11
|
+
/** Mount trusted compiler HTML with instance-specific anchor and accessibility IDs.
|
|
12
|
+
* This is not a sanitizer. The result must come from trusted compiler output.
|
|
13
|
+
* The mount replaces the container's children and rewrites local routing metadata.
|
|
14
|
+
* @param container DOM element receiving the content.
|
|
15
|
+
* @param result A validated HTML representation; Markdown results aren't accepted.
|
|
16
|
+
* @param options Optional unique instance ID and cancellation signal.
|
|
17
|
+
* @returns Rewritten anchors, typed links, and an unmount handle.
|
|
18
|
+
*/
|
|
8
19
|
export declare function mountContent(container: Element, result: ContentResult, options?: {
|
|
9
20
|
instanceId?: string;
|
|
10
21
|
signal?: AbortSignal;
|
package/dist/content-mount.js
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { ContentDeliveryError, contentRefKey } from './content-delivery-contract.js';
|
|
2
|
-
/** Mount trusted compiler
|
|
2
|
+
/** Mount trusted compiler HTML with instance-specific anchor and accessibility IDs.
|
|
3
|
+
* This is not a sanitizer. The result must come from trusted compiler output.
|
|
4
|
+
* The mount replaces the container's children and rewrites local routing metadata.
|
|
5
|
+
* @param container DOM element receiving the content.
|
|
6
|
+
* @param result A validated HTML representation; Markdown results aren't accepted.
|
|
7
|
+
* @param options Optional unique instance ID and cancellation signal.
|
|
8
|
+
* @returns Rewritten anchors, typed links, and an unmount handle.
|
|
9
|
+
*/
|
|
3
10
|
export function mountContent(container, result, options = {}) {
|
|
4
11
|
options.signal?.throwIfAborted();
|
|
5
12
|
if (result.format !== 'html')
|
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import type { ContentSnapshot, ContentPublication } from './content-delivery-contract.js';
|
|
2
2
|
import type { ContentDeliveryLimits } from './content-delivery.js';
|
|
3
|
+
/** Options for a REST inventory and its revision-pinned resource reads. */
|
|
3
4
|
export type RestContentSourceOptions = {
|
|
5
|
+
/** REST mount URL, such as /content/v1. Browser requests must use the application's origin. */
|
|
4
6
|
baseUrl: string | URL;
|
|
7
|
+
/** Exact publication to request; include product for a product-scoped source. */
|
|
5
8
|
publication: ContentPublication;
|
|
9
|
+
/** Expected inventory revision. Omit it to open the current revision. */
|
|
6
10
|
revision?: string;
|
|
11
|
+
/** Fetch implementation. Defaults to globalThis.fetch. */
|
|
7
12
|
fetch?: typeof globalThis.fetch;
|
|
13
|
+
/** Cancel the inventory-opening request. */
|
|
8
14
|
signal?: AbortSignal;
|
|
15
|
+
/** Inventory and representation bounds. */
|
|
9
16
|
limits?: ContentDeliveryLimits;
|
|
10
17
|
};
|
|
11
|
-
/**
|
|
18
|
+
/** Open a REST inventory and pin subsequent resource reads to its revision.
|
|
19
|
+
* @param options REST mount, exact publication, optional revision, and request settings.
|
|
20
|
+
* @returns A snapshot with the same list/get/dispose interface as the manifest source.
|
|
21
|
+
*/
|
|
12
22
|
export declare function openRestContentSource(options: RestContentSourceOptions): Promise<ContentSnapshot>;
|
|
@@ -7,7 +7,10 @@ const digestPattern = /^[a-f0-9]{64}$/;
|
|
|
7
7
|
const record = (value) => !!value && typeof value === 'object' && !Array.isArray(value);
|
|
8
8
|
const exactKeys = (value, keys) => record(value) && Object.keys(value).length === keys.length && Object.keys(value).every(key => keys.includes(key));
|
|
9
9
|
const invalid = (message) => { throw new ContentDeliveryError('invalid_manifest', message); };
|
|
10
|
-
/**
|
|
10
|
+
/** Open a REST inventory and pin subsequent resource reads to its revision.
|
|
11
|
+
* @param options REST mount, exact publication, optional revision, and request settings.
|
|
12
|
+
* @returns A snapshot with the same list/get/dispose interface as the manifest source.
|
|
13
|
+
*/
|
|
11
14
|
export async function openRestContentSource(options) {
|
|
12
15
|
let baseUrl;
|
|
13
16
|
try {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import type { ContentPublication, ContentRef, ContentResource } from './content-delivery-contract.js';
|
|
2
2
|
/** Public identity only: independent of publication, revision, and export filenames. */
|
|
3
3
|
export declare function contentResourceKey(ref: ContentRef): string;
|
|
4
|
+
/** One resource inventory entry with its REST lookup key. */
|
|
4
5
|
export type ContentRestEntry = {
|
|
5
6
|
key: string;
|
|
6
7
|
resource: ContentResource;
|
|
7
8
|
};
|
|
9
|
+
/** Revision-scoped inventory envelope returned by the content REST service. */
|
|
8
10
|
export type ContentRestList = {
|
|
9
11
|
schemaVersion: 1 | 2;
|
|
10
12
|
revision: string;
|
|
11
13
|
publication: ContentPublication;
|
|
12
14
|
resources: ContentRestEntry[];
|
|
13
15
|
};
|
|
16
|
+
/** Revision-scoped metadata envelope for a single content resource. */
|
|
14
17
|
export type ContentRestResource = {
|
|
15
18
|
schemaVersion: 1 | 2;
|
|
16
19
|
revision: string;
|
|
@@ -18,7 +21,9 @@ export type ContentRestResource = {
|
|
|
18
21
|
key: string;
|
|
19
22
|
resource: ContentResource;
|
|
20
23
|
};
|
|
24
|
+
/** Error categories used by the content REST protocol. */
|
|
21
25
|
export type ContentRestErrorCode = 'invalid_request' | 'not_found' | 'unsupported_format' | 'stale_revision' | 'method_not_allowed' | 'internal_error';
|
|
26
|
+
/** JSON error envelope returned by the content REST service. */
|
|
22
27
|
export type ContentRestError = {
|
|
23
28
|
error: {
|
|
24
29
|
code: ContentRestErrorCode;
|
package/dist/content-source.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export type Frontmatter = {
|
|
|
57
57
|
[key: string]: unknown;
|
|
58
58
|
};
|
|
59
59
|
export type Document = {
|
|
60
|
+
sectionSelection?: import('./section-selection.js').SectionSelection;
|
|
60
61
|
codeReference?: import('./code-reference-model.js').CodeReference;
|
|
61
62
|
featureContext?: import('./deployment-profile.js').FeatureContext;
|
|
62
63
|
change?: ResolvedChange;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SectionSelection } from './section-selection.js';
|
|
1
2
|
import { type Document, type Variant } from './content.js';
|
|
2
3
|
import { type AuthoredPublicationConfig } from './publication-plan.js';
|
|
3
4
|
import { type loadConfig } from './config.js';
|
|
@@ -5,7 +6,7 @@ import { type SnippetDefinition } from './snippets.js';
|
|
|
5
6
|
import type { ReaderFiltersConfig, ReaderSelection } from './reader-filters.js';
|
|
6
7
|
import type { loadMetadataProvider } from './metadata-provider.js';
|
|
7
8
|
/** Shared source resolution. No website navigation, styles, hosting or provider setup. */
|
|
8
|
-
export declare function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions }: {
|
|
9
|
+
export declare function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions, sectionSelection: suppliedSectionSelection }: {
|
|
9
10
|
base: string;
|
|
10
11
|
basePath: string;
|
|
11
12
|
config: AuthoredPublicationConfig & {
|
|
@@ -19,12 +20,14 @@ export declare function prepareContentWorkspace({ base, basePath, config, loaded
|
|
|
19
20
|
language: string;
|
|
20
21
|
readerFilters?: ReaderFiltersConfig;
|
|
21
22
|
contentFilter?: ReaderSelection;
|
|
23
|
+
sectionSelection?: SectionSelection;
|
|
22
24
|
metadataProvider?: Awaited<ReturnType<typeof loadMetadataProvider>>;
|
|
23
25
|
metadataDependencies: Set<string>;
|
|
24
26
|
sourceOverrides?: ReadonlyMap<string, string>;
|
|
25
27
|
authoringFiles?: ReadonlySet<string>;
|
|
26
28
|
allowRouteCollisions?: boolean;
|
|
27
29
|
}): Promise<{
|
|
30
|
+
sectionSelection: SectionSelection;
|
|
28
31
|
docs: Map<string, Document>;
|
|
29
32
|
knownDocumentIds: Set<string>;
|
|
30
33
|
knownDocumentTypes: Map<string, string>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createSectionSelection } from './section-selection.js';
|
|
1
2
|
import { documentKey } from './publication-identity.js';
|
|
2
3
|
import { matchesFeatures } from './deployment-profile.js';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -10,7 +11,8 @@ import { explainSegments } from './config.js';
|
|
|
10
11
|
import { validateSnippetConfig } from './snippets.js';
|
|
11
12
|
const keyFor = documentKey;
|
|
12
13
|
/** Shared source resolution. No website navigation, styles, hosting or provider setup. */
|
|
13
|
-
export async function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions }) {
|
|
14
|
+
export async function prepareContentWorkspace({ base, basePath, config, loaded, variants, language, readerFilters, contentFilter, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions, sectionSelection: suppliedSectionSelection }) {
|
|
15
|
+
const sectionSelection = suppliedSectionSelection ?? createSectionSelection(readerFilters, contentFilter, config.publications);
|
|
14
16
|
const { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir } = await planAuthoredDocuments({
|
|
15
17
|
base, basePath, config, variants, language, readerFilters, contentFilter, featureContext: loaded.deployment?.context, metadataProvider, metadataDependencies, sourceOverrides, authoringFiles, allowRouteCollisions
|
|
16
18
|
});
|
|
@@ -34,6 +36,7 @@ export async function prepareContentWorkspace({ base, basePath, config, loaded,
|
|
|
34
36
|
});
|
|
35
37
|
const { api, sourceForVariant, knownOperations } = apiPlan;
|
|
36
38
|
for (const [key, doc] of docs) {
|
|
39
|
+
doc.sectionSelection = sectionSelection;
|
|
37
40
|
doc.featureContext = loaded.deployment?.context;
|
|
38
41
|
for (const operationId of doc.frontmatter.operations ?? []) {
|
|
39
42
|
const known = knownOperations.get(operationId);
|
|
@@ -84,6 +87,6 @@ export async function prepareContentWorkspace({ base, basePath, config, loaded,
|
|
|
84
87
|
throw new Error(`no OpenAPI source for ${variant.channel}/${variant.version} (${operationId})`);
|
|
85
88
|
return { ...binding, sourceOperationId: operation.sourceOperationId };
|
|
86
89
|
};
|
|
87
|
-
return { docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir, snippets,
|
|
90
|
+
return { sectionSelection, docs, knownDocumentIds, knownDocumentTypes, authoredOperationIds, routeOwners, contentDir, snippets,
|
|
88
91
|
apiPlan, api, sourceForVariant, knownOperations, relatedApiTargets, guidesByApi, sourceForOperation };
|
|
89
92
|
}
|
|
@@ -34,7 +34,9 @@ export type ProfileResolution = {
|
|
|
34
34
|
export declare function validateFeatureClassification(source: Record<string, unknown>, context: FeatureContext | undefined, label: string): void;
|
|
35
35
|
export declare function featureRequirements(value: unknown, context: FeatureContext | undefined, label: string): FeatureRequirements | undefined;
|
|
36
36
|
export declare function matchesFeatures(value: unknown, context: FeatureContext | undefined, label: string, kind?: 'page' | 'section'): boolean;
|
|
37
|
-
/**
|
|
37
|
+
/** Evaluate a feature guard without expanding its children. */
|
|
38
|
+
export declare function evaluateFeatureGuard(node: any, context: FeatureContext | undefined, file: string, ancestorIncluded?: boolean, record?: boolean): boolean | undefined;
|
|
39
|
+
/** Compatibility entry point for consumers that only select feature grants. */
|
|
38
40
|
export declare function pruneFeatureTree(tree: any, context: FeatureContext | undefined, file: string): any;
|
|
39
41
|
/** Returned to the caller or written under .shoalrun, never a served artifact. */
|
|
40
42
|
export declare function profileSelection(resolution: ProfileResolution | undefined): {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { pruneConditionalTree } from './conditional-tree.js';
|
|
1
2
|
import { resolvePublication } from './compiler-config.js';
|
|
2
3
|
import { publicationKey } from './publication-identity.js';
|
|
3
4
|
import { readFile, lstat, realpath } from 'node:fs/promises';
|
|
@@ -69,26 +70,24 @@ export function matchesFeatures(value, context, label, kind = 'page') {
|
|
|
69
70
|
context?.decisions.push({ kind, id: label, included, ...(requirement ? { requires: requirement } : {}) });
|
|
70
71
|
return included;
|
|
71
72
|
}
|
|
72
|
-
/**
|
|
73
|
+
/** Evaluate a feature guard without expanding its children. */
|
|
74
|
+
export function evaluateFeatureGuard(node, context, file, ancestorIncluded = true, record = true) {
|
|
75
|
+
if (node.name !== 'ForFeature')
|
|
76
|
+
return;
|
|
77
|
+
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFeature>`;
|
|
78
|
+
const attributes = node.attributes ?? [];
|
|
79
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || !['allOf', 'anyOf'].includes(item.name) || typeof item.value !== 'string') || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
80
|
+
throw new Error(`${label} needs block content and distinct literal allOf/anyOf attributes`);
|
|
81
|
+
const requirements = Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/).filter(Boolean)]));
|
|
82
|
+
const target = !record && context ? { ...context, decisions: [] } : context;
|
|
83
|
+
const included = matchesFeatures(requirements, target, label, 'section');
|
|
84
|
+
if (!ancestorIncluded && target?.decisions.length)
|
|
85
|
+
target.decisions[target.decisions.length - 1].included = false;
|
|
86
|
+
return included;
|
|
87
|
+
}
|
|
88
|
+
/** Compatibility entry point for consumers that only select feature grants. */
|
|
73
89
|
export function pruneFeatureTree(tree, context, file) {
|
|
74
|
-
|
|
75
|
-
if (!node || typeof node !== 'object')
|
|
76
|
-
return [node];
|
|
77
|
-
if (node.name === 'ForFeature') {
|
|
78
|
-
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFeature>`;
|
|
79
|
-
const attributes = node.attributes ?? [];
|
|
80
|
-
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || !['allOf', 'anyOf'].includes(item.name) || typeof item.value !== 'string') || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
81
|
-
throw new Error(`${label} needs block content and distinct literal allOf/anyOf attributes`);
|
|
82
|
-
const requirements = Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/).filter(Boolean)]));
|
|
83
|
-
const included = matchesFeatures(requirements, context, label, 'section');
|
|
84
|
-
if (!parentIncluded && context?.decisions.length)
|
|
85
|
-
context.decisions[context.decisions.length - 1].included = false;
|
|
86
|
-
const children = node.children.flatMap((child) => walk(child, parentIncluded && included));
|
|
87
|
-
return included && parentIncluded ? children : [];
|
|
88
|
-
}
|
|
89
|
-
return [{ ...node, ...(node.children ? { children: node.children.flatMap((child) => walk(child, parentIncluded)) } : {}) }];
|
|
90
|
-
};
|
|
91
|
-
return walk(tree)[0];
|
|
90
|
+
return pruneConditionalTree(tree, (node, ancestorIncluded) => evaluateFeatureGuard(node, context, file, ancestorIncluded));
|
|
92
91
|
}
|
|
93
92
|
/** Returned to the caller or written under .shoalrun, never a served artifact. */
|
|
94
93
|
export function profileSelection(resolution) {
|
package/dist/palettes.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const paletteTokens: readonly ["text", "page", "surface", "link", "link-hover", "focus", "ink", "accent", "accent-contrast", "header-muted", "header-border", "border", "border-soft", "border-nested", "field-surface", "field-border", "field-accent", "presence-bg", "presence-text", "optional-bg", "optional-text", "muted", "nav-heading", "section-heading", "nav-text", "nav-hover", "nav-active", "nav-active-text", "deprecated-bg", "deprecated-text", "beta-bg", "beta-text", "development-bg", "development-text", "experimental-bg", "experimental-text", "emphasis", "summary", "code-bg", "code-text", "code-muted", "code-border", "code-block", "callout-line", "callout-bg", ...("callout-
|
|
1
|
+
export declare const paletteTokens: readonly ["text", "page", "surface", "link", "link-hover", "focus", "ink", "accent", "accent-contrast", "header-muted", "header-border", "border", "border-soft", "border-nested", "field-surface", "field-border", "field-accent", "presence-bg", "presence-text", "optional-bg", "optional-text", "muted", "nav-heading", "section-heading", "nav-text", "nav-hover", "nav-active", "nav-active-text", "deprecated-bg", "deprecated-text", "beta-bg", "beta-text", "development-bg", "development-text", "experimental-bg", "experimental-text", "emphasis", "summary", "code-bg", "code-text", "code-muted", "code-border", "code-block", "callout-line", "callout-bg", ...("callout-warning-line" | "callout-note-line" | "callout-tip-line" | "callout-important-line" | "callout-caution-line" | "callout-warning-bg" | "callout-note-bg" | "callout-tip-bg" | "callout-important-bg" | "callout-caution-bg" | "callout-warning-text" | "callout-note-text" | "callout-tip-text" | "callout-important-text" | "callout-caution-text")[], "strong-surface", "strong-text"];
|
|
2
2
|
export type Token = typeof paletteTokens[number];
|
|
3
3
|
export type Mode = 'light' | 'dark';
|
|
4
4
|
export type Palette = {
|
|
@@ -34,7 +34,7 @@ export function buildPublicationManifest({ configPublications, fictionalDocument
|
|
|
34
34
|
...(taxonomy ? { taxonomy } : {}),
|
|
35
35
|
dependencies,
|
|
36
36
|
...(tabs.length ? { navigationTabs: tabs } : {}),
|
|
37
|
-
documents: rendered.map(({ doc, markdown, sections }) => ({ id: doc.frontmatter.id, demo: fictionalDocuments.has(doc), type: doc.frontmatter.type, title: doc.frontmatter.title, summary: doc.frontmatter.summary, subjectLifecycle: doc.frontmatter.subjectLifecycle ?? null, ...(doc.change ? { change: doc.change } : {}), ...(doc.subjectDeprecation ? { subjectDeprecation: doc.subjectDeprecation } : {}), variant: doc.variant, url: doc.route, markdownUrl: doc.markdownRoute, ...tabFor(doc), indexable: indexable(doc), ...(updatedFor(doc) ? { updated: updatedFor(doc) } : {}), ...(doc.frontmatter.availability ? { availability: doc.frontmatter.availability } : {}), ...(doc.frontmatter.verified ? { verified: doc.frontmatter.verified } : {}), contentDigest: doc.contentDigest, breadcrumbs: navigationPath(resolvedNavigation.get(publicationKey(doc.variant)) ?? [], doc.route), ...(doc.frontmatter.product !== undefined ? { product: doc.frontmatter.product } : {}), ...(doc.frontmatter.area !== undefined ? { area: doc.frontmatter.area } : {}), ...(doc.frontmatter.subarea !== undefined ? { subarea: doc.frontmatter.subarea } : {}), ...(readerFilters ? { readerFilters: doc.readerFilters ?? {} } : {}), cardTargets: cardUses.get(doc)?.targets ?? [], cardQueries: cardUses.get(doc)?.queries ?? [], snippets: [...new Set(snippetUses.filter(use => use.documentId === doc.frontmatter.id).map(use => use.id))], apiEmbeds: apiEmbedUses.filter(use => use.documentKey === keyFor(doc.frontmatter.id, doc.variant)).map(({ sourceFile, documentKey, ...request }) => request), focusedContractUrl: doc.focusedContractUrl ?? null, focusedContractBytes: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.bytes : null, focusedContractDigest: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.digest : null, sections: (sections ?? []).map(({ content, ...record }) => record), ...markdownSize(markdown), digest: digest(markdown) })),
|
|
37
|
+
documents: rendered.map(({ doc, markdown, sections }) => ({ id: doc.frontmatter.id, demo: fictionalDocuments.has(doc), type: doc.frontmatter.type, title: doc.frontmatter.title, summary: doc.frontmatter.summary, subjectLifecycle: doc.frontmatter.subjectLifecycle ?? null, ...(doc.change ? { change: doc.change } : {}), ...(doc.subjectDeprecation ? { subjectDeprecation: doc.subjectDeprecation } : {}), variant: doc.variant, url: doc.route, markdownUrl: doc.markdownRoute, ...tabFor(doc), indexable: indexable(doc), ...(updatedFor(doc) ? { updated: updatedFor(doc) } : {}), ...(doc.frontmatter.availability ? { availability: doc.frontmatter.availability } : {}), ...(doc.frontmatter.verified ? { verified: doc.frontmatter.verified } : {}), contentDigest: doc.contentDigest, breadcrumbs: navigationPath(resolvedNavigation.get(publicationKey(doc.variant)) ?? [], doc.route), ...(doc.frontmatter.product !== undefined ? { product: doc.frontmatter.product } : {}), ...(doc.frontmatter.area !== undefined ? { area: doc.frontmatter.area } : {}), ...(doc.frontmatter.subarea !== undefined ? { subarea: doc.frontmatter.subarea } : {}), ...(readerFilters ? { readerFilters: doc.readerFilters ?? {} } : {}), cardTargets: cardUses.get(doc)?.targets ?? [], cardQueries: cardUses.get(doc)?.queries ?? [], snippets: [...new Set(snippetUses.filter(use => (use.documentKey ? use.documentKey === keyFor(doc.frontmatter.id, doc.variant) : use.documentId === doc.frontmatter.id)).map(use => use.id))], apiEmbeds: apiEmbedUses.filter(use => use.documentKey === keyFor(doc.frontmatter.id, doc.variant)).map(({ sourceFile, documentKey, ...request }) => request), focusedContractUrl: doc.focusedContractUrl ?? null, focusedContractBytes: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.bytes : null, focusedContractDigest: doc.focusedContractUrl ? focusedContracts.get(doc.focusedContractUrl)?.digest : null, sections: (sections ?? []).map(({ content, ...record }) => record), ...markdownSize(markdown), digest: digest(markdown) })),
|
|
38
38
|
operations,
|
|
39
39
|
relationships: publishedRelationships,
|
|
40
40
|
redirects,
|
|
@@ -20,8 +20,14 @@ export function publicTree(tree, representation, documentRoutes, mode = 'light',
|
|
|
20
20
|
element('div', { 'data-component-content': '' }, children)
|
|
21
21
|
])];
|
|
22
22
|
}
|
|
23
|
-
if (node.type === 'docRepresentation')
|
|
24
|
-
|
|
23
|
+
if (node.type === 'docRepresentation') {
|
|
24
|
+
if (node.representation !== representation)
|
|
25
|
+
return [];
|
|
26
|
+
const children = node.children.flatMap(walk);
|
|
27
|
+
// Mark HTML-only content so agent-parity checks can distinguish intentional
|
|
28
|
+
// format-specific prose from accidental content loss in the Markdown twin.
|
|
29
|
+
return representation === 'html' ? [element('div', { 'data-markdown-ignore': '' }, children)] : children;
|
|
30
|
+
}
|
|
25
31
|
if (node.type === 'docCookbookChooser') {
|
|
26
32
|
const prompt = node.mode === 'single' ? 'Choose one recipe.' : 'Choose one or more recipes.';
|
|
27
33
|
const details = (option) => [option.when ? `Use when: ${option.when}` : option.summary, option.needs ? `You need: ${option.needs}` : '', option.outcome ? `You will have: ${option.outcome}` : ''].filter(Boolean);
|
package/dist/search-query.js
CHANGED
|
@@ -64,7 +64,7 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
64
64
|
return [];
|
|
65
65
|
const termScore = (term) => weight(title, term, title.startsWith(term.term) ? 12 : 8, true) || weight(summary, term, 4) || (headings.some(heading => match(heading, term)) ? 3 : 0) || weight(body, term, 1);
|
|
66
66
|
let score = terms.reduce((total, term) => total + termScore(term), 0);
|
|
67
|
-
|
|
67
|
+
let contentScore = terms.filter(term => !fallbackStopWords.has(term.term)).reduce((total, term) => total + termScore(term), 0);
|
|
68
68
|
const prominentMatches = terms.filter(term => !fallbackStopWords.has(term.term) && (matchTitle(title, term) || match(summary, term) || headings.some(heading => match(heading, term)))).length;
|
|
69
69
|
const section = terms.every(term => matchTitle(title, term)) ? undefined : doc.headings.find((heading, at) => terms.every(term => match(headings[at], term)));
|
|
70
70
|
// Use only query terms with meaning, and require a unique matching section.
|
|
@@ -77,8 +77,10 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
77
77
|
// older indexes and unreviewed sections conservatively retain the full page.
|
|
78
78
|
const selected = candidates.length === 1 && candidates[0].standalone === true ? candidates[0] : undefined;
|
|
79
79
|
// A complete multiword section-title match outranks incidental page-title words.
|
|
80
|
-
if (meaningful.length >= 2 && candidates.some(candidate => meaningful.every(term => match(candidate.title.toLocaleLowerCase(), term))))
|
|
80
|
+
if (meaningful.length >= 2 && candidates.some(candidate => meaningful.every(term => match(candidate.title.toLocaleLowerCase(), term)))) {
|
|
81
81
|
score += 20;
|
|
82
|
+
contentScore += 20;
|
|
83
|
+
}
|
|
82
84
|
const { product, channel, version, language } = parsePublicationKey(doc.variant);
|
|
83
85
|
const tokens = selected?.markdownTokens ?? doc.markdownTokens;
|
|
84
86
|
const read = { tool: selected ? 'get_section' : 'get_page', arguments: {
|
|
@@ -87,15 +89,20 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
87
89
|
} };
|
|
88
90
|
return [{ score, contentScore, prominentMatches, matched: matched.length, partialMatched: matched.filter(term => !fallbackStopWords.has(term.term)).length, id: doc.id, type: doc.type, title: doc.title, summary: doc.summary, url: section ? `${doc.url}#${section.id}` : doc.url, markdownUrl: selected?.markdownUrl ?? doc.markdownUrl, pageMarkdownUrl: doc.markdownUrl, read, ...(tokens !== undefined ? { markdownTokens: tokens, markdownBytes: selected?.markdownBytes ?? doc.markdownBytes, markdownTokenEncoding: doc.markdownTokenEncoding } : {}), ...(selected || section ? { section: selected?.title ?? section?.title } : {}), snippet: excerpt(doc.text, terms.flatMap(unit => [unit.term, ...unit.alternatives])) }];
|
|
89
91
|
});
|
|
90
|
-
const
|
|
92
|
+
const contentTerms = terms.filter(term => !fallbackStopWords.has(term.term)).length;
|
|
93
|
+
// Filler words shape the sentence, not the subject. A page that covers every
|
|
94
|
+
// content term is complete even when it omits "how", "do", or "the"; otherwise
|
|
95
|
+
// a page that happens to repeat filler words can hide the focused result.
|
|
96
|
+
const complete = contentTerms === 0
|
|
97
|
+
? hits.filter(hit => hit.matched === terms.length)
|
|
98
|
+
: hits.filter(hit => hit.partialMatched === contentTerms);
|
|
91
99
|
// Relax the all-words gate only when complete matches are entirely incidental
|
|
92
100
|
// body matches. A near-complete result must cover all but one content term and
|
|
93
101
|
// have a stronger non-filler field score. Title/summary/heading matches on any
|
|
94
102
|
// complete result preserve the original preference; filler cannot earn promotion.
|
|
95
|
-
const contentTerms = terms.filter(term => !fallbackStopWords.has(term.term)).length;
|
|
96
103
|
const bestCompleteContent = Math.max(...complete.map(hit => hit.contentScore));
|
|
97
104
|
const stronger = complete.length && contentTerms >= 3 && complete.every(hit => hit.prominentMatches === 0)
|
|
98
|
-
? hits.filter(hit => hit.
|
|
105
|
+
? hits.filter(hit => hit.partialMatched < contentTerms && hit.partialMatched >= contentTerms - 1
|
|
99
106
|
&& hit.prominentMatches > 0 && hit.contentScore > bestCompleteContent) : [];
|
|
100
107
|
const ranked = complete.length ? [...complete, ...stronger] : hits.filter(hit => hit.partialMatched > 0);
|
|
101
108
|
// In partial fallback, one extra incidental word must not outweigh a focused
|
|
@@ -114,7 +121,7 @@ export async function queryBuiltSite(directory, query, options = {}) {
|
|
|
114
121
|
if (aNear && a.contentScore !== b.contentScore)
|
|
115
122
|
return b.contentScore - a.contentScore;
|
|
116
123
|
}
|
|
117
|
-
return (complete.length ? b.
|
|
124
|
+
return (complete.length ? b.contentScore - a.contentScore : b.partialMatched - a.partialMatched) || b.score - a.score || a.title.localeCompare(b.title) || a.id.localeCompare(b.id);
|
|
118
125
|
});
|
|
119
126
|
const publication = parsePublicationKey(variants[0]);
|
|
120
127
|
return { status: 'ok', query: query.trim(), publication, total: ranked.length, matchMode: stronger.length ? 'mixed' : complete.length ? 'all' : 'partial', results: ranked.slice(0, limit).map(({ matched, partialMatched, contentScore, prominentMatches, ...result }) => result) };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ReaderFiltersConfig, type ReaderSelection } from './reader-filters.js';
|
|
2
|
+
import type { CompilerPublicationsConfig } from './compiler-config.js';
|
|
3
|
+
import type { Document } from './content-source.js';
|
|
4
|
+
export type SectionSelection = {
|
|
5
|
+
facets?: ReaderFiltersConfig;
|
|
6
|
+
selection?: ReaderSelection;
|
|
7
|
+
decisions: Map<string, Record<string, unknown>>;
|
|
8
|
+
warnings: Map<string, {
|
|
9
|
+
code: string;
|
|
10
|
+
message: string;
|
|
11
|
+
}>;
|
|
12
|
+
hasConditions: boolean;
|
|
13
|
+
publications?: CompilerPublicationsConfig;
|
|
14
|
+
};
|
|
15
|
+
export declare function createSectionSelection(facets?: ReaderFiltersConfig, selection?: ReaderSelection, publications?: CompilerPublicationsConfig): SectionSelection;
|
|
16
|
+
/** Share publication validation with pruning so receipts reflect every build-time ancestor. */
|
|
17
|
+
export declare function evaluatePublicationGuard(node: any, doc: Document, file: string, publications?: CompilerPublicationsConfig): boolean | undefined;
|
|
18
|
+
export declare function pruneSelectedTree(tree: any, doc: Document, file?: string, record?: boolean): any;
|
|
19
|
+
export declare function warnReaderSection(doc: Document, file: string, line: number, requirements: ReaderSelection): void;
|
|
20
|
+
export declare function sectionSelectionReport(context: SectionSelection): {
|
|
21
|
+
selection: ReaderSelection | null;
|
|
22
|
+
decisions: Record<string, unknown>[];
|
|
23
|
+
warnings: {
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
}[];
|
|
27
|
+
};
|
|
28
|
+
/** Keep receipts private, atomic, and keyed by artifact so nested exports can't replace a site's record. */
|
|
29
|
+
export declare function writeSectionSelectionReport(base: string, context: SectionSelection, artifact: Record<string, unknown>): Promise<void>;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdir, writeFile, rename, rm } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { pruneConditionalTree } from './conditional-tree.js';
|
|
5
|
+
import { evaluateFeatureGuard } from './deployment-profile.js';
|
|
6
|
+
import { matchesSectionContentFilter } from './content-filter.js';
|
|
7
|
+
import { validateReaderSelection } from './reader-filters.js';
|
|
8
|
+
import { documentKey } from './publication-identity.js';
|
|
9
|
+
export function createSectionSelection(facets, selection, publications) {
|
|
10
|
+
return { facets, selection, publications, decisions: new Map(), warnings: new Map(), hasConditions: false };
|
|
11
|
+
}
|
|
12
|
+
/** Share publication validation with pruning so receipts reflect every build-time ancestor. */
|
|
13
|
+
export function evaluatePublicationGuard(node, doc, file, publications) {
|
|
14
|
+
if (node.name !== 'ForPublication')
|
|
15
|
+
return;
|
|
16
|
+
const attributes = node.attributes ?? [];
|
|
17
|
+
const allowed = ['product', 'channel', 'version', 'language'];
|
|
18
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || typeof item.value !== 'string' || !allowed.includes(item.name) || !item.value.trim()) || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
19
|
+
throw new Error(`${file}: <ForPublication> needs block content and distinct literal product, channel, version, or language attributes`);
|
|
20
|
+
const product = attributes.find((item) => item.name === 'product')?.value ?? doc.variant.product;
|
|
21
|
+
for (const item of attributes) {
|
|
22
|
+
const catalog = item.name === 'product' ? publications?.products : item.name === 'channel' ? publications?.channels : item.name === 'version' ? (product ? publications?.products?.[product]?.versions : publications?.versions) : undefined;
|
|
23
|
+
if (publications && item.name !== 'language' && (!catalog || !Object.hasOwn(catalog, item.value)))
|
|
24
|
+
throw new Error(`${file}: <ForPublication> names unknown ${item.name} ${item.value}`);
|
|
25
|
+
}
|
|
26
|
+
return !attributes.some((item) => doc.variant[item.name] !== item.value);
|
|
27
|
+
}
|
|
28
|
+
export function pruneSelectedTree(tree, doc, file = doc.file, record = true) {
|
|
29
|
+
const context = doc.sectionSelection;
|
|
30
|
+
return pruneConditionalTree(tree, (node, ancestorIncluded) => {
|
|
31
|
+
if (node.name === 'ForPublication')
|
|
32
|
+
return evaluatePublicationGuard(node, doc, file, context?.publications);
|
|
33
|
+
if (node.name === 'ForFeature')
|
|
34
|
+
return evaluateFeatureGuard(node, doc.featureContext, file, ancestorIncluded, record);
|
|
35
|
+
if (node.name !== 'ForFacet')
|
|
36
|
+
return;
|
|
37
|
+
const label = `${file}:${node.position?.start?.line ?? 1}: <ForFacet>`;
|
|
38
|
+
const attributes = node.attributes ?? [];
|
|
39
|
+
if (node.type !== 'mdxJsxFlowElement' || !node.children?.length || !attributes.length || attributes.some((item) => item.type !== 'mdxJsxAttribute' || typeof item.value !== 'string' || !item.value.trim()) || new Set(attributes.map((item) => item.name)).size !== attributes.length)
|
|
40
|
+
throw new Error(`${label} needs block content and distinct nonempty literal facet attributes`);
|
|
41
|
+
if (!context?.facets)
|
|
42
|
+
throw new Error(`${label} needs configured readerFilters.facets`);
|
|
43
|
+
const requirements = validateReaderSelection(Object.fromEntries(attributes.map((item) => [item.name, item.value.trim().split(/\s+/)])), context.facets, label);
|
|
44
|
+
context.hasConditions = true;
|
|
45
|
+
const match = matchesSectionContentFilter(requirements, context.selection);
|
|
46
|
+
if (record) {
|
|
47
|
+
const line = node.position?.start?.line ?? 1;
|
|
48
|
+
const key = JSON.stringify([documentKey(doc.frontmatter.id, doc.variant), file, line, requirements, ancestorIncluded]);
|
|
49
|
+
context.decisions.set(key, { documentId: doc.frontmatter.id, publication: doc.variant, source: file, line, requirements, localMatch: match, included: ancestorIncluded && match, reason: !ancestorIncluded ? 'ancestor-excluded' : match ? 'matched' : 'facet-mismatch' });
|
|
50
|
+
}
|
|
51
|
+
return match;
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
export function warnReaderSection(doc, file, line, requirements) {
|
|
55
|
+
const context = doc.sectionSelection;
|
|
56
|
+
if (!context?.selection)
|
|
57
|
+
return;
|
|
58
|
+
const overlap = Object.keys(requirements).filter(facet => context.selection?.[facet]);
|
|
59
|
+
if (!overlap.length)
|
|
60
|
+
return;
|
|
61
|
+
const key = JSON.stringify([file, line, overlap]);
|
|
62
|
+
if (context.warnings.has(key))
|
|
63
|
+
return;
|
|
64
|
+
const message = `${file}:${line}: <ReaderSection> uses build-selected facet(s) ${overlap.join(', ')} but only changes reader visibility; its content remains in the output. Use <ForFacet> to omit unmatched content during this build.`;
|
|
65
|
+
context.warnings.set(key, { code: 'reader-section-build-facet', message });
|
|
66
|
+
process.stderr.write(`warning [reader-section-build-facet] ${message}\n`);
|
|
67
|
+
}
|
|
68
|
+
export function sectionSelectionReport(context) {
|
|
69
|
+
return { selection: context.selection ?? null, decisions: [...context.decisions.values()], warnings: [...context.warnings.values()] };
|
|
70
|
+
}
|
|
71
|
+
/** Keep receipts private, atomic, and keyed by artifact so nested exports can't replace a site's record. */
|
|
72
|
+
export async function writeSectionSelectionReport(base, context, artifact) {
|
|
73
|
+
const folder = path.join(base, '.shoalrun');
|
|
74
|
+
await mkdir(folder, { recursive: true });
|
|
75
|
+
const file = path.join(folder, 'content-selection.json');
|
|
76
|
+
const key = createHash('sha256').update(JSON.stringify(artifact.target)).digest('hex');
|
|
77
|
+
const receipt = { schemaVersion: 1, ...artifact, ...sectionSelectionReport(context) };
|
|
78
|
+
const receipts = path.join(folder, 'content-selection');
|
|
79
|
+
await mkdir(receipts, { recursive: true });
|
|
80
|
+
const atomic = async (destination, value) => {
|
|
81
|
+
const temporary = path.join(folder, `.content-selection-${randomUUID()}.json`);
|
|
82
|
+
try {
|
|
83
|
+
await writeFile(temporary, JSON.stringify(value, null, 2) + '\n');
|
|
84
|
+
await rename(temporary, destination);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
await rm(temporary, { force: true });
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
await atomic(path.join(receipts, key + '.json'), receipt);
|
|
91
|
+
await atomic(file, { ...receipt, receipt: `content-selection/${key}.json` });
|
|
92
|
+
}
|
package/dist/snippets.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type SnippetUse = {
|
|
|
13
13
|
id: string;
|
|
14
14
|
file: string;
|
|
15
15
|
documentId: string;
|
|
16
|
+
documentKey?: string;
|
|
16
17
|
};
|
|
17
18
|
export declare function validateSnippetConfig(id: string, definition: any): Record<string, SnippetVariable>;
|
|
18
19
|
export declare function snippetAttribute(attribute: any, label: string): unknown;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Additional information in a selected build
|
|
2
|
+
|
|
3
|
+
This example uses one shared page, with an internal operations section. It needs
|
|
4
|
+
no customer profile or feature manifest. From this directory, with Shoalrun installed:
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
shoalrun build docs.config.yaml dist/complete
|
|
8
|
+
shoalrun build customer.config.yaml dist/customer
|
|
9
|
+
shoalrun serve dist/complete --port 8771
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Open <http://127.0.0.1:8771/>. In another terminal, serve the customer output:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
shoalrun serve dist/customer --port 8772
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Open <http://127.0.0.1:8772/>. Both sites show **Review a bill** and **Get help**.
|
|
19
|
+
Only the complete build has **Check the retry queue**. Check `index.md` and
|
|
20
|
+
`search-index.json` in each output: the customer files must contain neither that
|
|
21
|
+
heading nor its instructions. The unfiltered build includes all valid blocks.
|
|
22
|
+
|
|
23
|
+
**Unmarked sections stay included. Unmarked pages are excluded when a selected
|
|
24
|
+
facet has no matching page mark.** This page explicitly belongs to both audiences.
|
|
25
|
+
`<ForFacet audience="internal partner">` would accept either choice if both were
|
|
26
|
+
configured; multiple facet attributes must all match. A facet the build doesn't
|
|
27
|
+
filter passes automatically. Selection removes sections rather than swapping
|
|
28
|
+
variants. Use positive literal matches only.
|
|
29
|
+
|
|
30
|
+
`<ReaderSection>` is different: it hides content in browser views while publishing
|
|
31
|
+
it in output files. Never use it to omit internal instructions from a customer
|
|
32
|
+
build. Build-time omission doesn't authenticate the complete site's deployment.
|
|
33
|
+
|
|
34
|
+
After each successful build, `.shoalrun/content-selection.json` records its target
|
|
35
|
+
and section decisions. Follow its `receipt` path for the artifact-specific copy;
|
|
36
|
+
these reports belong outside served output. Portable exports need their own
|
|
37
|
+
`contentFilter`; PDF exports inherit the site's filter unless overridden.
|