@shoalrun/cli 0.1.0-alpha.12 → 0.1.0-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +45 -5
- 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/support.md +11 -10
- package/agent-docs/author/components.md +13 -1
- package/agent-docs/author/frontmatter-reference.md +28 -25
- package/agent-docs/author/frontmatter-reference.sections/choose-a-publication-and-visibility.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/control-output-details.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/global-defaults-and-enforced-values.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/html-markdown-and-agents.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/identify-and-route-a-page.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/point-agents-to-it.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/project-defined-fields.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/related-reading.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/use-the-local-files-while-authoring.md +3 -1
- package/agent-docs/author/frontmatter-reference.sections/when-the-files-update.md +3 -1
- package/agent-docs/author/frontmatter.md +5 -2
- package/agent-docs/author/frontmatter.sections/audience-badges.md +1 -1
- package/agent-docs/author/frontmatter.sections/give-deprecation-guidance.md +1 -1
- package/agent-docs/author/frontmatter.sections/global-defaults-and-enforced-values.md +1 -1
- package/agent-docs/author/frontmatter.sections/optional-native-fields.md +5 -2
- package/agent-docs/author/frontmatter.sections/publication-fields.md +1 -1
- package/agent-docs/author/frontmatter.sections/publishing-policy.md +1 -1
- package/agent-docs/author/frontmatter.sections/related-metadata-tasks.md +1 -1
- package/agent-docs/author/frontmatter.sections/related-reading.md +1 -1
- package/agent-docs/author/frontmatter.sections/required-after-inheritance.md +1 -1
- package/agent-docs/author/frontmatter.sections/seo-fields.md +1 -1
- package/agent-docs/author/frontmatter.sections/validation-rules.md +1 -1
- package/agent-docs/author/markdown-metadata.md +13 -5
- package/agent-docs/author/navigation.md +12 -1
- package/agent-docs/author/navigation.sections/arrange-authored-pages.md +1 -1
- package/agent-docs/author/navigation.sections/fill-an-api-tag-group.md +1 -1
- package/agent-docs/author/navigation.sections/hide-group-page-counts.md +12 -1
- package/agent-docs/author/navigation.sections/html-markdown-and-agents.md +1 -1
- package/agent-docs/author/navigation.sections/local-api-preview.md +1 -1
- package/agent-docs/author/navigation.sections/mix-guides-and-api-references.md +1 -1
- package/agent-docs/author/navigation.sections/optionally-split-a-large-menu-into-files.md +1 -1
- package/agent-docs/author/navigation.sections/reach-navigation-while-reading.md +1 -1
- package/agent-docs/author/navigation.sections/related-reading.md +1 -1
- package/agent-docs/author/navigation.sections/split-navigation-into-tabs.md +1 -1
- package/agent-docs/author/navigation.sections/subject-lifecycle-labels.md +1 -1
- package/agent-docs/author/templates.md +10 -2
- package/agent-docs/author/templates.sections/built-in-feature-templates.md +1 -1
- package/agent-docs/author/templates.sections/built-in-templates.md +1 -1
- package/agent-docs/author/templates.sections/choose-formatting-enforcement-for-your-project.md +1 -1
- package/agent-docs/author/templates.sections/create-or-edit-a-project-template.md +10 -2
- package/agent-docs/author/templates.sections/keep-the-four-shapes-distinct.md +1 -1
- package/agent-docs/author/templates.sections/project-added-templates.md +1 -1
- package/agent-docs/author/templates.sections/related-reading.md +1 -1
- package/agent-docs/author/templates.sections/scaffold-a-page.md +1 -1
- package/agent-docs/author/templates.sections/short-cli-and-derived-values.md +1 -1
- package/agent-docs/author/templates.sections/what-every-template-gives-you.md +1 -1
- package/agent-docs/author/workspace.md +7 -1
- package/agent-docs/author/writing-style.md +13 -1
- package/agent-docs/author/writing-style.sections/adapt-this-example.md +1 -1
- package/agent-docs/author/writing-style.sections/choose-components-by-reader-need.md +1 -1
- package/agent-docs/author/writing-style.sections/evidence-and-uncertainty.md +1 -1
- package/agent-docs/author/writing-style.sections/example-audience-and-scope.md +1 -1
- package/agent-docs/author/writing-style.sections/feature-availability.md +36 -0
- package/agent-docs/author/writing-style.sections/ingredients-recipes-and-cookbooks.md +1 -1
- package/agent-docs/author/writing-style.sections/page-purpose-and-structure.md +1 -1
- package/agent-docs/author/writing-style.sections/procedures-and-examples.md +1 -1
- package/agent-docs/author/writing-style.sections/related-reading.md +1 -1
- package/agent-docs/author/writing-style.sections/review-a-draft.md +1 -1
- package/agent-docs/author/writing-style.sections/reviewed-writing-examples.md +1 -1
- package/agent-docs/author/writing-style.sections/voice-and-explanations.md +1 -1
- package/agent-docs/changelog/2026-10-28.md +89 -0
- package/agent-docs/changelog.md +9 -1
- package/agent-docs/config/outputs.md +15 -11
- package/agent-docs/config/outputs.sections/exports.md +14 -11
- package/agent-docs/config/outputs.sections/metadata.md +1 -1
- package/agent-docs/config/outputs.sections/related-reading.md +1 -1
- package/agent-docs/content-delivery/agents.md +86 -0
- package/agent-docs/content-delivery/api.md +130 -0
- package/agent-docs/content-delivery/client.md +79 -0
- package/agent-docs/content-delivery/http-api/operations/get-content-representation-fa1d2e3f.md +394 -0
- package/agent-docs/content-delivery/http-api/operations/get-content-representation-head-4052375c.md +256 -0
- package/agent-docs/content-delivery/http-api/operations/get-content-resource-849f1c49.md +911 -0
- package/agent-docs/content-delivery/http-api/operations/get-content-resource-head-0a352acd.md +246 -0
- package/agent-docs/content-delivery/http-api/operations/list-content-resources-8e977ec7.md +913 -0
- package/agent-docs/content-delivery/http-api/operations/list-content-resources-head-b67cbad9.md +236 -0
- package/agent-docs/content-delivery/http-api.md +78 -0
- package/agent-docs/content-delivery/manifest.md +79 -0
- package/agent-docs/content-delivery/publish.md +72 -0
- package/agent-docs/content-delivery/render.md +73 -0
- package/agent-docs/content-delivery/rest.md +108 -0
- package/agent-docs/content-delivery/sections.md +110 -0
- package/agent-docs/content-delivery/select.md +100 -0
- package/agent-docs/content-delivery.md +79 -0
- package/agent-docs/documents.json +6748 -5073
- package/agent-docs/provenance.json +4 -4
- package/agent-docs/publish/content-export.md +32 -16
- package/agent-docs/publish/content-export.sections/assets-downloads-and-notices.md +3 -3
- package/agent-docs/publish/content-export.sections/check-the-result.md +2 -2
- package/agent-docs/publish/content-export.sections/export-selected-pages.md +12 -9
- package/agent-docs/publish/content-export.sections/inspect-the-manifest.md +5 -3
- package/agent-docs/publish/content-export.sections/prerequisites.md +3 -3
- package/agent-docs/publish/content-export.sections/related-reading.md +2 -2
- package/agent-docs/publish/content-export.sections/review-exported-api-material.md +3 -3
- package/agent-docs/publish/content-export.sections/try-the-help-drawer-example.md +3 -3
- package/agent-docs/publish/content-export.sections/upgrade-an-existing-integration.md +34 -0
- package/agent-docs/publish/content-export.sections/what-the-representations-retain.md +4 -4
- package/agent-docs/publish/mcp.md +3 -1
- package/agent-docs/publish/mcp.sections/check-budgets-and-errors.md +1 -1
- package/agent-docs/publish/mcp.sections/choose-the-documentation-source.md +1 -1
- package/agent-docs/publish/mcp.sections/configure-the-client.md +1 -1
- package/agent-docs/publish/mcp.sections/generate-a-vercel-endpoint.md +1 -1
- package/agent-docs/publish/mcp.sections/related-reading.md +3 -1
- package/agent-docs/publish/mcp.sections/search-then-read.md +1 -1
- package/agent-docs/publish/mcp.sections/serve-a-public-endpoint-on-node.md +1 -1
- package/agent-docs/publish/mcp.sections/verify-the-connection.md +1 -1
- package/agent-docs/publish/mcp.sections/why-offer-mcp-for-public-docs.md +1 -1
- package/agent-docs/publish/seo.md +16 -2
- package/agent-docs/publish/seo.sections/related-reading.md +28 -0
- package/agent-docs/publish/seo.sections/set-the-public-address.md +36 -0
- package/agent-docs/publish/seo.sections/what-agents-receive.md +28 -0
- package/agent-docs/publish/seo.sections/what-the-build-adds.md +42 -0
- package/agent-docs/publish/seo.sections/write-the-page-title-and-summary.md +43 -0
- package/agent-docs/search-index.json +1 -1
- package/agent-docs/styling/layouts.md +21 -3
- package/agent-docs/styling/layouts.sections/build-a-landing-page.md +6 -3
- package/agent-docs/styling/layouts.sections/build-a-splash-page.md +6 -3
- package/agent-docs/styling/layouts.sections/control-navigation-tabs.md +6 -3
- package/agent-docs/styling/layouts.sections/customize-the-hero.md +6 -3
- package/agent-docs/styling/layouts.sections/hero.md +6 -3
- package/agent-docs/styling/layouts.sections/hide-the-table-of-contents-or-give-content-more-room.md +54 -0
- package/agent-docs/styling/layouts.sections/html-markdown-and-agents.md +6 -3
- package/agent-docs/styling/layouts.sections/related-reading.md +6 -3
- package/dist/api.js +70 -3
- package/dist/authoring-hints.d.ts +3 -0
- package/dist/authoring-hints.js +35 -0
- package/dist/authoring-project.d.ts +1 -1
- package/dist/authoring-project.js +2 -0
- package/dist/authoring-validation.js +2 -0
- package/dist/code-samples.js +22 -11
- package/dist/compiler-config.d.ts +1 -0
- package/dist/compiler-config.js +13 -0
- package/dist/compiler.js +2 -1
- package/dist/component-names.js +1 -1
- package/dist/component-transform.js +7 -1
- package/dist/content-delivery-contract.d.ts +108 -0
- package/dist/content-delivery-contract.js +15 -0
- package/dist/content-delivery-transport.d.ts +3 -0
- package/dist/content-delivery-transport.js +47 -0
- package/dist/content-delivery-validation.d.ts +7 -0
- package/dist/content-delivery-validation.js +122 -0
- package/dist/content-delivery.d.ts +21 -0
- package/dist/content-delivery.js +119 -0
- package/dist/content-export-anchors.d.ts +11 -0
- package/dist/content-export-anchors.js +79 -0
- package/dist/content-export-command.d.ts +4 -2
- package/dist/content-export-command.js +15 -2
- package/dist/content-export-comparison.d.ts +16 -0
- package/dist/content-export-comparison.js +48 -0
- package/dist/content-export-config.d.ts +17 -0
- package/dist/content-export-config.js +47 -3
- package/dist/content-export-render.js +20 -1
- package/dist/content-export.d.ts +5 -1
- package/dist/content-export.js +193 -40
- package/dist/content-mount.d.ts +11 -0
- package/dist/content-mount.js +73 -0
- package/dist/content-rest-client.d.ts +12 -0
- package/dist/content-rest-client.js +162 -0
- package/dist/content-rest-contract.d.ts +27 -0
- package/dist/content-rest-contract.js +9 -0
- package/dist/content-rest-server.d.ts +7 -0
- package/dist/content-rest-server.js +99 -0
- package/dist/content-source.d.ts +3 -1
- package/dist/frontmatter.js +8 -7
- package/dist/html-renderer.js +25 -0
- package/dist/markdown-sections.d.ts +2 -1
- package/dist/markdown-sections.js +8 -18
- package/dist/page-renderer.js +5 -3
- package/dist/publication-plan.js +2 -1
- package/dist/scaffold-placeholders.d.ts +2 -0
- package/dist/scaffold-placeholders.js +19 -0
- package/dist/section-identity.d.ts +24 -0
- package/dist/section-identity.js +137 -0
- package/examples/content-delivery/README.md +87 -0
- package/examples/content-delivery/app.js +91 -0
- package/examples/content-delivery/content/billing.mdx +22 -0
- package/examples/content-delivery/docs.config.yaml +36 -0
- package/examples/content-delivery/index.html +25 -0
- package/examples/content-delivery/preview.mjs +86 -0
- package/examples/content-delivery/snippets/refund-window.mdx +3 -0
- package/examples/help-drawer/README.md +2 -2
- package/examples/help-drawer/app.js +3 -3
- package/package.json +6 -3
- package/schemas/content-export.schema.json +469 -33
- package/schemas/content-rest.openapi.json +1627 -0
- package/skills/shoalrun-author/SKILL.md +2 -0
- package/styles/site.css +4 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,9 +17,11 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
23
|
+
|
|
24
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
22
25
|
|
|
23
26
|
| Layout | Sidebar | On this page | Use it for |
|
|
24
27
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -33,6 +36,21 @@ layout: wide
|
|
|
33
36
|
|
|
34
37
|
An unknown value fails the build. Each preset styles all four layouts, and project CSS can target one through `html[data-layout="wide"]`, `html[data-layout="landing"]`, or `html[data-layout="splash"]`.
|
|
35
38
|
|
|
39
|
+
## Hide the table of contents or give content more room
|
|
40
|
+
|
|
41
|
+
To remove the right sidebar labeled “On this page” and widen the content area, set `layout: wide`. It keeps the left navigation and gives interactive tools, large tables, and diagrams more space.
|
|
42
|
+
|
|
43
|
+
To hide the table of contents without choosing a different layout, set `tocDepth: 0`. To keep an outline with fewer heading levels, use `tocDepth: 2`. See [page metadata](https://www.shoalrun.com/author/frontmatter.md) for the supported depths.
|
|
44
|
+
|
|
45
|
+
These settings serve different goals:
|
|
46
|
+
|
|
47
|
+
| Goal | Page frontmatter |
|
|
48
|
+
| ------------------------------------------------------------ | ------------------------------------- |
|
|
49
|
+
| Give interactive content more space while keeping navigation | `layout: wide` |
|
|
50
|
+
| Hide “On this page” within the current layout | `tocDepth: 0` |
|
|
51
|
+
| Keep “On this page” but list only main sections | `tocDepth: 2` |
|
|
52
|
+
| Remove navigation and the outline for an entry page | `layout: landing` or `layout: splash` |
|
|
53
|
+
|
|
36
54
|
## Control navigation tabs
|
|
37
55
|
|
|
38
56
|
The built-in layouts are `docs`, `wide`, `landing`, and `splash`. There is no `custom` layout value; use landing or splash for a custom entry page and style it with project CSS.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
package/agent-docs/styling/layouts.sections/hide-the-table-of-contents-or-give-content-more-room.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: guide.layouts
|
|
3
|
+
title: Page layouts, landing pages, and splash pages
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
6
|
+
type: reference
|
|
7
|
+
area: appearance
|
|
8
|
+
subarea: appearance-layouts
|
|
9
|
+
canonical: /styling/layouts
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Page layouts, landing pages, and splash pages
|
|
13
|
+
|
|
14
|
+
> Documentation index: [llms.min.txt](https://www.shoalrun.com/llms.min.txt) · Document manifest: [documents.json](https://www.shoalrun.com/documents.json)
|
|
15
|
+
|
|
16
|
+
Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigation/docs-50f26fe22670.txt) (ID: docs). [All sections and pages](https://www.shoalrun.com/llms.min.txt)
|
|
17
|
+
|
|
18
|
+
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
19
|
+
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
21
|
+
|
|
22
|
+
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
23
|
+
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
27
|
+
|
|
28
|
+
| Layout | Sidebar | On this page | Use it for |
|
|
29
|
+
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
30
|
+
| `docs` | Yes | Yes | Guides and reference pages. This is the default. |
|
|
31
|
+
| `wide` | Yes | No | Wide tables, diagrams, and API overviews that need the full content width. |
|
|
32
|
+
| `landing` | No | No | Home pages and product entry points. A `Hero` replaces the page header. |
|
|
33
|
+
| `splash` | No | No | Marketing pages built from full-width bands. A `Hero` replaces the page header, and `Section` blocks stack edge to edge. |
|
|
34
|
+
|
|
35
|
+
```yaml title="Frontmatter"
|
|
36
|
+
layout: wide
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
An unknown value fails the build. Each preset styles all four layouts, and project CSS can target one through `html[data-layout="wide"]`, `html[data-layout="landing"]`, or `html[data-layout="splash"]`.
|
|
40
|
+
|
|
41
|
+
## Hide the table of contents or give content more room
|
|
42
|
+
|
|
43
|
+
To remove the right sidebar labeled “On this page” and widen the content area, set `layout: wide`. It keeps the left navigation and gives interactive tools, large tables, and diagrams more space.
|
|
44
|
+
|
|
45
|
+
To hide the table of contents without choosing a different layout, set `tocDepth: 0`. To keep an outline with fewer heading levels, use `tocDepth: 2`. See [page metadata](https://www.shoalrun.com/author/frontmatter.md) for the supported depths.
|
|
46
|
+
|
|
47
|
+
These settings serve different goals:
|
|
48
|
+
|
|
49
|
+
| Goal | Page frontmatter |
|
|
50
|
+
| ------------------------------------------------------------ | ------------------------------------- |
|
|
51
|
+
| Give interactive content more space while keeping navigation | `layout: wide` |
|
|
52
|
+
| Hide “On this page” within the current layout | `tocDepth: 0` |
|
|
53
|
+
| Keep “On this page” but list only main sections | `tocDepth: 2` |
|
|
54
|
+
| Remove navigation and the outline for an entry page | `layout: landing` or `layout: splash` |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: guide.layouts
|
|
3
3
|
title: Page layouts, landing pages, and splash pages
|
|
4
|
-
summary:
|
|
4
|
+
summary: Hide the table of contents, give interactive content more space, or
|
|
5
|
+
build landing and splash pages.
|
|
5
6
|
type: reference
|
|
6
7
|
area: appearance
|
|
7
8
|
subarea: appearance-layouts
|
|
@@ -16,11 +17,13 @@ Navigation section: [Docs](https://www.shoalrun.com/.well-known/shoalrun/navigat
|
|
|
16
17
|
|
|
17
18
|
Breadcrumbs: [Docs](https://www.shoalrun.com/what-is-shoalrun.md) > Configure and customize > Page layouts, landing pages, and splash pages
|
|
18
19
|
|
|
19
|
-
**Updated: 2026-10-
|
|
20
|
+
**Updated: 2026-10-28.**
|
|
20
21
|
|
|
21
22
|
Parent page: [Full Markdown page](/styling/layouts.md)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
Use `layout: wide` to hide “On this page” and give interactive content more space while keeping navigation. Use `tocDepth: 0` when you only want to hide the table of contents within the current layout.
|
|
25
|
+
|
|
26
|
+
Every page uses the `docs` layout unless its frontmatter sets `layout`. Choose the page structure first, then adjust individual visibility settings. Layouts change the HTML page only. The Markdown twin, search, and `llms.txt` stay the same.
|
|
24
27
|
|
|
25
28
|
| Layout | Sidebar | On this page | Use it for |
|
|
26
29
|
| --------- | ------- | ------------ | ------------------------------------------------------------------------------------------------------------------------ |
|
package/dist/api.js
CHANGED
|
@@ -224,7 +224,7 @@ export class ApiReader {
|
|
|
224
224
|
if (entries.length === 1 && /^[^?&#\s=]+$/.test(entries[0][0]) && ['string', 'number', 'boolean'].includes(typeof entries[0][1]))
|
|
225
225
|
queryExpression = `${entries[0][0]}=${encodeURIComponent(String(entries[0][1]))}`;
|
|
226
226
|
}
|
|
227
|
-
if (location.startsWith('parameter:')) {
|
|
227
|
+
if (location.startsWith('parameter:') || location.startsWith('response-header:')) {
|
|
228
228
|
const value = example.externalValue ? link(example.externalValue, 'Open external example') : inline(queryRule && location === `parameter:query:${queryRule.parameter}` ? queryExpression ?? JSON.stringify(example.value) : JSON.stringify(example.value));
|
|
229
229
|
const sample = paragraph({ type: 'strong', children: [text(example.title)] }, text(': '), value, ...(example.description ? [text(` — ${example.description}`)] : []));
|
|
230
230
|
sample.data = { hProperties: { className: ['api-parameter-example'] } };
|
|
@@ -465,8 +465,8 @@ export class ApiReader {
|
|
|
465
465
|
blocks.push(heading(3, 'Responses'));
|
|
466
466
|
for (const [status, initial] of Object.entries(op.responses ?? {})) {
|
|
467
467
|
const { value: response, source: responseSource } = await this.deref(pathSource, initial);
|
|
468
|
-
if (response.
|
|
469
|
-
throw new Error(`Response
|
|
468
|
+
if (response.links)
|
|
469
|
+
throw new Error(`Response links need an adapter: ${status}`);
|
|
470
470
|
const description = String(response.description ?? '').trim();
|
|
471
471
|
const mediaEntries = Object.entries(response.content ?? {});
|
|
472
472
|
const responseBlocks = [];
|
|
@@ -474,6 +474,73 @@ export class ApiReader {
|
|
|
474
474
|
responseBlocks.push({ type: 'docApiResponseHeader', data: { hName: 'div', hProperties: { className: ['api-response-header'] } }, children: [responseHeading, ...mediaEntries.map(([mediaType]) => ({ ...paragraph(inline(mediaType)), data: { hProperties: { className: ['api-response-media'] } } }))] });
|
|
475
475
|
if (description)
|
|
476
476
|
responseBlocks.push(...parsePlainMarkdown(description));
|
|
477
|
+
if (response.headers !== undefined && (!response.headers || typeof response.headers !== 'object' || Array.isArray(response.headers)))
|
|
478
|
+
throw new Error(`Response headers must be a mapping: ${status}`);
|
|
479
|
+
const headerNames = new Set();
|
|
480
|
+
const headers = [];
|
|
481
|
+
for (const [name, initialHeader] of Object.entries(response.headers ?? {})) {
|
|
482
|
+
// OpenAPI explicitly excludes Content-Type: response.content describes it.
|
|
483
|
+
if (name.toLowerCase() === 'content-type')
|
|
484
|
+
continue;
|
|
485
|
+
if (!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/.test(name))
|
|
486
|
+
throw new Error(`Invalid response header name: ${name}`);
|
|
487
|
+
if (headerNames.has(name.toLowerCase()))
|
|
488
|
+
throw new Error(`Duplicate response header name (case-insensitive): ${name}`);
|
|
489
|
+
headerNames.add(name.toLowerCase());
|
|
490
|
+
let header = initialHeader, headerSource = responseSource;
|
|
491
|
+
let overrideDescription;
|
|
492
|
+
const seen = new Set();
|
|
493
|
+
while (header?.$ref) {
|
|
494
|
+
if (typeof header.$ref !== 'string')
|
|
495
|
+
throw new Error(`Response header reference must be a string: ${name}`);
|
|
496
|
+
const allowed = schemaVersion === '3.1' ? ['$ref', 'description', 'summary'] : ['$ref'];
|
|
497
|
+
if (Object.keys(header).some(key => !allowed.includes(key)))
|
|
498
|
+
throw new Error(`Response header reference ${name} has unsupported siblings`);
|
|
499
|
+
for (const field of ['description', 'summary'])
|
|
500
|
+
if (header[field] !== undefined && typeof header[field] !== 'string')
|
|
501
|
+
throw new Error(`Invalid response header reference ${field}: ${name}`);
|
|
502
|
+
// Reference summary has no Header Object counterpart; OAS ignores it.
|
|
503
|
+
if (overrideDescription === undefined && header.description !== undefined)
|
|
504
|
+
overrideDescription = header.description;
|
|
505
|
+
const resolved = await this.ref(headerSource, header.$ref);
|
|
506
|
+
if (seen.has(resolved.identity))
|
|
507
|
+
throw new Error(`Recursive response header reference: ${name}`);
|
|
508
|
+
seen.add(resolved.identity);
|
|
509
|
+
header = resolved.value;
|
|
510
|
+
headerSource = resolved.source;
|
|
511
|
+
}
|
|
512
|
+
if (!header || typeof header !== 'object' || Array.isArray(header))
|
|
513
|
+
throw new Error(`Invalid response Header Object: ${name}`);
|
|
514
|
+
if (header.content !== undefined)
|
|
515
|
+
throw new Error(`Response header content needs an adapter: ${name}`);
|
|
516
|
+
const fields = new Set(['description', 'required', 'deprecated', 'schema', 'style', 'explode', 'example', 'examples']);
|
|
517
|
+
for (const field of Object.keys(header))
|
|
518
|
+
if (!fields.has(field) && !field.startsWith('x-'))
|
|
519
|
+
throw new Error(`Unsupported response header field ${field}: ${name}`);
|
|
520
|
+
for (const field of ['required', 'deprecated', 'explode'])
|
|
521
|
+
if (header[field] !== undefined && typeof header[field] !== 'boolean')
|
|
522
|
+
throw new Error(`Response header ${field} must be boolean: ${name}`);
|
|
523
|
+
if (header.description !== undefined && typeof header.description !== 'string')
|
|
524
|
+
throw new Error(`Response header description must be a string: ${name}`);
|
|
525
|
+
if (header.style !== undefined && header.style !== 'simple')
|
|
526
|
+
throw new Error(`Response header style must be simple: ${name}`);
|
|
527
|
+
if (header.schema === undefined)
|
|
528
|
+
throw new Error(`Response header requires a schema: ${name}`);
|
|
529
|
+
if (header.examples !== undefined && (!header.examples || typeof header.examples !== 'object' || Array.isArray(header.examples)))
|
|
530
|
+
throw new Error(`Response header examples must be a mapping: ${name}`);
|
|
531
|
+
const headerDescription = overrideDescription ?? header.description;
|
|
532
|
+
const detail = [heading(6, name), tagged(paragraph(text(header.required ? 'Required' : 'Optional')), 'api-parameter-presence', { 'data-required': header.required ? 'true' : 'false' })];
|
|
533
|
+
if (header.deprecated)
|
|
534
|
+
detail.push(tagged(paragraph(text('Deprecated response header.')), 'api-deprecated-note'));
|
|
535
|
+
if (headerDescription)
|
|
536
|
+
detail.push(...parsePlainMarkdown(headerDescription));
|
|
537
|
+
detail.push(paragraph(text(`Serialization: simple; explode: ${header.explode ?? false}.`)));
|
|
538
|
+
detail.push(...await this.schemaBlocks(headerSource, header.schema, schemaVersion, 6, new Set(), ['response', status, 'header', name], [], headerDescription));
|
|
539
|
+
await addExamples(headerSource, header, `response-header:${name}`, null, status, detail);
|
|
540
|
+
headers.push({ type: 'docApiParameter', data: { hName: 'section', hProperties: { className: ['api-parameter', 'api-response-header-field'] } }, children: detail });
|
|
541
|
+
}
|
|
542
|
+
if (headers.length)
|
|
543
|
+
responseBlocks.push(heading(5, 'Response headers'), ...headers);
|
|
477
544
|
for (const [mediaType, media] of mediaEntries) {
|
|
478
545
|
if (mediaEntries.length > 1)
|
|
479
546
|
responseBlocks.push(tagged(heading(5, mediaType), 'api-media-heading'));
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { parse } from './semantic-markdown.js';
|
|
2
|
+
const text = (node) => typeof node.value === 'string' ? node.value : (node.children ?? []).map(text).join('');
|
|
3
|
+
const contains = (node, predicate) => predicate(node) || (node.children ?? []).some((child) => contains(child, predicate));
|
|
4
|
+
/** Suggestions only: the author decides whether native relationships fit the links. */
|
|
5
|
+
export function authoringHints(body, file) {
|
|
6
|
+
let tree;
|
|
7
|
+
try {
|
|
8
|
+
tree = parse.parse(body);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return [];
|
|
12
|
+
} // Compilation reports syntax errors.
|
|
13
|
+
if (contains(tree, node => node.name === 'RelatedReading'))
|
|
14
|
+
return [];
|
|
15
|
+
const nodes = tree.children ?? [];
|
|
16
|
+
const definitions = new Map();
|
|
17
|
+
contains(tree, node => { if (node.type === 'definition')
|
|
18
|
+
definitions.set(node.identifier, node.url); return false; });
|
|
19
|
+
const documentLink = (node) => node.type === 'link' && node.url?.startsWith('doc:') || node.type === 'linkReference' && definitions.get(node.identifier)?.startsWith('doc:');
|
|
20
|
+
for (let index = 0; index < nodes.length; index++) {
|
|
21
|
+
const heading = nodes[index];
|
|
22
|
+
if (heading.type !== 'heading' || !/^related (reading|materials?)$/i.test(text(heading).trim()))
|
|
23
|
+
continue;
|
|
24
|
+
let end = index + 1;
|
|
25
|
+
while (end < nodes.length && !(nodes[end].type === 'heading' && nodes[end].depth <= heading.depth))
|
|
26
|
+
end++;
|
|
27
|
+
if (!nodes.slice(index + 1, end).some((node) => contains(node, documentLink)))
|
|
28
|
+
continue;
|
|
29
|
+
return [{ code: 'authoring.related-reading', severity: 'warning', file,
|
|
30
|
+
explanation: 'This page has a related-reading or related-material section with document links. Native relationships and RelatedReading may suit these connections.',
|
|
31
|
+
reference: 'guide.related-reading',
|
|
32
|
+
nextAction: 'Read guide.related-reading and guide.component.related-reading. Inspect the purpose and reason for each connection before choosing native relationships; keep manual links when they better fit the page.' }];
|
|
33
|
+
}
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
@@ -27,7 +27,7 @@ export declare const projectToolFailure: (error: unknown) => {
|
|
|
27
27
|
schemaVersion: number;
|
|
28
28
|
status: "error";
|
|
29
29
|
error: {
|
|
30
|
-
code: "invalid_input" | "internal_error" | "
|
|
30
|
+
code: "invalid_input" | "internal_error" | "unsafe_path" | "unknown_source" | "invalid_project";
|
|
31
31
|
message: string;
|
|
32
32
|
};
|
|
33
33
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { authoringHints } from './authoring-hints.js';
|
|
1
2
|
import { createHash } from 'node:crypto';
|
|
2
3
|
import { readFile, readdir, realpath } from 'node:fs/promises';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -121,6 +122,7 @@ export async function inspectAuthoringProject(configFile, options = {}) {
|
|
|
121
122
|
publication: { channel: fm.channel ?? value.publications?.defaults?.channel, version: fm.version ?? value.publications?.defaults?.version, language: fm.language ?? defaultLanguage(value), ...(fm.publications ? { publications: fm.publications } : {}) },
|
|
122
123
|
access: fm.access ?? null, aliases: [] });
|
|
123
124
|
bodies.set(relative(file), doc.body);
|
|
125
|
+
findings.push(...authoringHints(doc.body, relative(file)).map(({ location, ...hint }) => hint));
|
|
124
126
|
}
|
|
125
127
|
catch (error) {
|
|
126
128
|
findings.push({ code: 'project.invalid-page', severity: 'error', file: relative(file), explanation: error.message, nextAction: 'Repair the page metadata and inspect again.', reference: 'guide.frontmatter' });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { authoringHints } from './authoring-hints.js';
|
|
1
2
|
import { chmod, mkdir, mkdtemp, readFile, readdir, realpath, stat, writeFile } from 'node:fs/promises';
|
|
2
3
|
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
@@ -188,6 +189,7 @@ export async function validateAuthoringChangesWithHooks(configFile, options, hoo
|
|
|
188
189
|
for (const file of affected) {
|
|
189
190
|
try {
|
|
190
191
|
const doc = await readDocument(path.join(shadow, file), loaded.value.frontmatter, undefined, capture.buffers.get(file).toString('utf8'));
|
|
192
|
+
report.findings.push(...authoringHints(doc.body, file));
|
|
191
193
|
if (!/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(doc.frontmatter.id))
|
|
192
194
|
report.findings.push({ ...finding('validation.identity', 'Page IDs must begin with a letter/digit and contain only letters, digits, dots, underscores or hyphens.', 'Choose a stable ID and update its references.'), file, reference: 'guide.frontmatter-reference' });
|
|
193
195
|
}
|
package/dist/code-samples.js
CHANGED
|
@@ -37,9 +37,10 @@ function resolve(sample) {
|
|
|
37
37
|
headers.push(['Content-Type', sample.contentType]);
|
|
38
38
|
return { headers, notes };
|
|
39
39
|
}
|
|
40
|
+
const isHead = (sample) => sample.method.toUpperCase() === 'HEAD';
|
|
40
41
|
const hasBody = (sample) => !!sample.body && !sample.body.formFields.length;
|
|
41
42
|
function curl(sample) {
|
|
42
|
-
const parts = [`curl --request ${sample.method.toUpperCase()}`, `--url ${shellQuote(sample.url)}`];
|
|
43
|
+
const parts = [isHead(sample) ? 'curl --head' : `curl --request ${sample.method.toUpperCase()}`, `--url ${shellQuote(sample.url)}`];
|
|
43
44
|
for (const auth of sample.auth) {
|
|
44
45
|
if (auth.kind === 'header')
|
|
45
46
|
parts.push(`--header ${shellQuote(`${auth.name}: ${auth.value}`)}`);
|
|
@@ -76,7 +77,11 @@ function javascript(sample, node) {
|
|
|
76
77
|
const lines = notes.map(note => `// ${note}`);
|
|
77
78
|
if (node)
|
|
78
79
|
lines.push('// Node.js 18 or newer provides a global fetch.');
|
|
79
|
-
lines.push(`const response = await fetch(${JSON.stringify(sample.url)}, {`, options.join(',\n'), '});', ''
|
|
80
|
+
lines.push(`const response = await fetch(${JSON.stringify(sample.url)}, {`, options.join(',\n'), '});', '');
|
|
81
|
+
if (isHead(sample))
|
|
82
|
+
lines.push('console.log(response.status, Object.fromEntries(response.headers));');
|
|
83
|
+
else
|
|
84
|
+
lines.push('const body = await response.text();', "const mediaType = (response.headers.get('content-type') ?? '').split(';')[0].trim().toLowerCase();", "const data = body && (mediaType === 'application/json' || mediaType.endsWith('+json')) ? JSON.parse(body) : body;", 'console.log(data);');
|
|
80
85
|
return lines.join('\n');
|
|
81
86
|
}
|
|
82
87
|
function python(sample) {
|
|
@@ -87,12 +92,16 @@ function python(sample) {
|
|
|
87
92
|
if (hasBody(sample))
|
|
88
93
|
lines.push(`data = ${JSON.stringify(sample.body.text)}`);
|
|
89
94
|
const args = ['url', ...(headers.length ? ['headers=headers'] : []), ...(hasBody(sample) ? ['data=data'] : [])];
|
|
90
|
-
lines.push('', `response = requests.${sample.method.toLowerCase()}(${args.join(', ')})
|
|
95
|
+
lines.push('', `response = requests.${sample.method.toLowerCase()}(${args.join(', ')})`);
|
|
96
|
+
if (isHead(sample))
|
|
97
|
+
lines.push('print(response.status_code, dict(response.headers))');
|
|
98
|
+
else
|
|
99
|
+
lines.push('body = response.text', "media_type = response.headers.get('Content-Type', '').split(';')[0].strip().lower()", "data = response.json() if body and (media_type == 'application/json' or media_type.endswith('+json')) else body", 'print(data)');
|
|
91
100
|
return lines.join('\n');
|
|
92
101
|
}
|
|
93
102
|
function go(sample) {
|
|
94
103
|
const { headers, notes } = resolve(sample);
|
|
95
|
-
const imports = ['"fmt"', '"io"', '"net/http"', ...(hasBody(sample) ? ['"strings"'] : [])].sort();
|
|
104
|
+
const imports = ['"fmt"', ...(isHead(sample) ? [] : ['"io"']), '"net/http"', ...(hasBody(sample) ? ['"strings"'] : [])].sort();
|
|
96
105
|
const bodyVar = hasBody(sample) ? [`body := strings.NewReader(${goString(sample.body.text)})`, ''] : [];
|
|
97
106
|
const bodyArg = hasBody(sample) ? 'body' : 'nil';
|
|
98
107
|
const lines = [
|
|
@@ -103,8 +112,7 @@ function go(sample) {
|
|
|
103
112
|
'\tif err != nil {', '\t\tpanic(err)', '\t}',
|
|
104
113
|
...headers.map(([name, value]) => `\treq.Header.Set(${JSON.stringify(name)}, ${JSON.stringify(value)})`),
|
|
105
114
|
'\tres, err := http.DefaultClient.Do(req)', '\tif err != nil {', '\t\tpanic(err)', '\t}',
|
|
106
|
-
'\tdefer res.Body.Close()', '\tdata, err := io.ReadAll(res.Body)', '\tif err != nil {', '\t\tpanic(err)', '\t}',
|
|
107
|
-
'\tfmt.Println(string(data))', '}'
|
|
115
|
+
'\tdefer res.Body.Close()', ...(isHead(sample) ? ['\tfmt.Println(res.StatusCode, res.Header)'] : ['\tdata, err := io.ReadAll(res.Body)', '\tif err != nil {', '\t\tpanic(err)', '\t}', '\tfmt.Println(string(data))']), '}'
|
|
108
116
|
];
|
|
109
117
|
return lines.join('\n');
|
|
110
118
|
}
|
|
@@ -117,12 +125,14 @@ function java(sample) {
|
|
|
117
125
|
'import java.net.URI;', 'import java.net.http.HttpClient;', 'import java.net.http.HttpRequest;', 'import java.net.http.HttpResponse;', '',
|
|
118
126
|
'public class Main {', ' public static void main(String[] args) throws Exception {', ' HttpClient client = HttpClient.newHttpClient();',
|
|
119
127
|
' HttpRequest request = HttpRequest.newBuilder()', ` .uri(URI.create(${JSON.stringify(sample.url)}))`, ...builder, bodyMethod, ' .build();',
|
|
120
|
-
' HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());', ' System.out.println(response.body());', ' }', '}'
|
|
128
|
+
' HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());', ...(isHead(sample) ? [' System.out.println(response.statusCode());', ' System.out.println(response.headers().map());'] : [' System.out.println(response.body());']), ' }', '}'
|
|
121
129
|
].join('\n');
|
|
122
130
|
}
|
|
123
131
|
function php(sample) {
|
|
124
132
|
const { headers, notes } = resolve(sample);
|
|
125
133
|
const array = [' CURLOPT_URL => ' + phpString(sample.url), ` CURLOPT_CUSTOMREQUEST => ${phpString(sample.method.toUpperCase())}`, ' CURLOPT_RETURNTRANSFER => true'];
|
|
134
|
+
if (isHead(sample))
|
|
135
|
+
array.push(' CURLOPT_NOBODY => true', ' CURLOPT_HEADER => true');
|
|
126
136
|
if (headers.length)
|
|
127
137
|
array.push(` CURLOPT_HTTPHEADER => [\n${headers.map(([name, value]) => ` ${phpString(`${name}: ${value}`)}`).join(',\n')}\n ]`);
|
|
128
138
|
if (hasBody(sample))
|
|
@@ -136,15 +146,16 @@ function php(sample) {
|
|
|
136
146
|
}
|
|
137
147
|
function ruby(sample) {
|
|
138
148
|
const { headers, notes } = resolve(sample);
|
|
139
|
-
const
|
|
149
|
+
const method = sample.method.toLowerCase();
|
|
150
|
+
const klass = method[0].toUpperCase() + method.slice(1);
|
|
140
151
|
const lines = [
|
|
141
152
|
...notes.map(note => `# ${note}`),
|
|
142
153
|
"require 'net/http'", "require 'uri'", '',
|
|
143
|
-
`uri = URI(${rubyString(sample.url)})`, 'http = Net::HTTP.new(uri.host, uri.port)', 'http.use_ssl =
|
|
154
|
+
`uri = URI(${rubyString(sample.url)})`, 'http = Net::HTTP.new(uri.host, uri.port)', 'http.use_ssl = uri.scheme == \'https\'', '',
|
|
144
155
|
`request = Net::HTTP::${klass}.new(uri)`,
|
|
145
156
|
...headers.map(([name, value]) => `request[${rubyString(name)}] = ${rubyString(value)}`),
|
|
146
157
|
...(hasBody(sample) ? [`request.body = ${rubyString(sample.body.text)}`] : []),
|
|
147
|
-
'', 'response = http.request(request)', 'puts response.body'
|
|
158
|
+
'', 'response = http.request(request)', ...(isHead(sample) ? ['puts response.code', 'puts response.to_hash'] : ['puts response.body'])
|
|
148
159
|
];
|
|
149
160
|
return lines.join('\n');
|
|
150
161
|
}
|
|
@@ -159,7 +170,7 @@ function csharp(sample) {
|
|
|
159
170
|
` var request = new HttpRequestMessage(new HttpMethod(${JSON.stringify(sample.method.toUpperCase())}), ${JSON.stringify(sample.url)});`,
|
|
160
171
|
...contentHeaders.map(([name, value]) => ` request.Headers.TryAddWithoutValidation(${JSON.stringify(name)}, ${JSON.stringify(value)});`),
|
|
161
172
|
...(hasBody(sample) ? [` request.Content = new StringContent(${csharpString(sample.body.text)}, Encoding.UTF8, ${JSON.stringify(contentType)});`] : []),
|
|
162
|
-
' var response = await client.SendAsync(request);', ' Console.WriteLine(await response.Content.ReadAsStringAsync());', ' }', '}'
|
|
173
|
+
' var response = await client.SendAsync(request);', ...(isHead(sample) ? [' Console.WriteLine((int)response.StatusCode);', ' Console.WriteLine(response.Headers);', ' Console.WriteLine(response.Content.Headers);'] : [' Console.WriteLine(await response.Content.ReadAsStringAsync());']), ' }', '}'
|
|
163
174
|
].join('\n');
|
|
164
175
|
}
|
|
165
176
|
// cURL comes first: the Markdown twin and agent bundle keep only that one.
|
|
@@ -58,6 +58,7 @@ export declare function configField(value: unknown, key: string): unknown;
|
|
|
58
58
|
export declare function resolvedCompilerConfig(value: unknown): ResolvedCompilerConfig;
|
|
59
59
|
/** A section-level mapping guard for validators that accept arbitrary YAML. */
|
|
60
60
|
export declare function configMappingAt(value: unknown, setting: string): ConfigMapping;
|
|
61
|
+
export declare function navigationHeading(outputs: unknown): string | false;
|
|
61
62
|
export declare function navigationCounts(outputs: unknown): boolean;
|
|
62
63
|
/**
|
|
63
64
|
* Apply the compiler's existing required-section checks at their original
|
package/dist/compiler-config.js
CHANGED
|
@@ -18,6 +18,19 @@ export function configMappingAt(value, setting) {
|
|
|
18
18
|
throw new Error(`${setting} must be a mapping`);
|
|
19
19
|
return value;
|
|
20
20
|
}
|
|
21
|
+
export function navigationHeading(outputs) {
|
|
22
|
+
const navigation = configField(configField(outputs, 'html'), 'navigation');
|
|
23
|
+
if (navigation === undefined)
|
|
24
|
+
return 'Explore';
|
|
25
|
+
const heading = configMappingAt(navigation, 'outputs.html.navigation').heading;
|
|
26
|
+
if (heading === undefined)
|
|
27
|
+
return 'Explore';
|
|
28
|
+
if (heading === false)
|
|
29
|
+
return false;
|
|
30
|
+
if (typeof heading !== 'string' || !heading.trim())
|
|
31
|
+
throw new Error('outputs.html.navigation.heading must be nonempty text or false');
|
|
32
|
+
return heading.trim();
|
|
33
|
+
}
|
|
21
34
|
export function navigationCounts(outputs) {
|
|
22
35
|
const navigation = configField(configField(outputs, 'html'), 'navigation');
|
|
23
36
|
if (navigation === undefined)
|