From 67de27a76c3ea59b7e68298fd516c4f7c1d06299 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:56:57 -0400 Subject: [PATCH 1/4] Add enterprise admonition and sidebar ENT badge Custom :::enterprise admonition with Stacklok symbol icon and teal color palette. Sidebar enterprise-only class with ENT pill badge and hover tooltip. Examples on theme-preview page. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/theme-preview.mdx | 14 ++++++++ docusaurus.config.ts | 4 +++ sidebars.ts | 6 +++- src/css/custom.css | 63 ++++++++++++++++++++++++++++++++++ src/theme/Admonition/Types.tsx | 46 +++++++++++++++++++++++++ 5 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/theme/Admonition/Types.tsx diff --git a/docs/theme-preview.mdx b/docs/theme-preview.mdx index bac15d71..c0c609a5 100644 --- a/docs/theme-preview.mdx +++ b/docs/theme-preview.mdx @@ -174,6 +174,20 @@ This is getting silly ::::: +Custom `:::enterprise` admonition for inline Enterprise upsell content. Uses the +Stacklok symbol as the icon and a teal color palette distinct from the other +admonition types. Supports custom titles via `:::enterprise[My title]`. + +:::enterprise + +Stacklok Enterprise includes turnkey integrations for common identity providers. +Instead of manually configuring OIDC, use the built-in Okta or Entra ID +integration to map IdP groups directly to ToolHive roles and policy sets. + +[Learn more about Stacklok Enterprise](/toolhive/enterprise). + +::: + ## Tables A standard Markdown table: diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 6ac68b95..0e47e307 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -171,6 +171,10 @@ const config: Config = { // Populate lastUpdatedAt metadata for JSON-LD structured data. // The rendered timestamp is hidden via CSS (.theme-last-updated). showLastUpdateTime: true, + admonitions: { + keywords: ['enterprise'], + extendDefaults: true, + }, }, blog: { blogTitle: 'ToolHive Updates and Announcements', diff --git a/sidebars.ts b/sidebars.ts index e891b856..d1f2288b 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -291,7 +291,11 @@ const sidebars: SidebarsConfig = { 'toolhive/reference/index', 'toolhive/reference/authz-policy-reference', 'toolhive/faq', - 'toolhive/enterprise', + { + type: 'doc', + id: 'toolhive/enterprise', + className: 'enterprise-only', + }, 'toolhive/support', 'toolhive/contributing', ], diff --git a/src/css/custom.css b/src/css/custom.css index 328673b2..720dc94e 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -382,6 +382,69 @@ details summary:hover { --ifm-alert-foreground-color: var(--stacklok-green-light); } +/* Enterprise admonitions - teal */ +.alert--enterprise { + --ifm-alert-background-color: #d5f0ec; + --ifm-alert-border-color: #1a8a7d; + --ifm-alert-foreground-color: #0f4f48; +} + +[data-theme='dark'] .alert--enterprise { + --ifm-alert-background-color: #1a3330; + --ifm-alert-border-color: #2a9d8f; + --ifm-alert-foreground-color: #c8ece7; +} + +/* Sidebar badge for enterprise-only pages */ +.enterprise-only > .menu__link { + position: relative; +} + +.enterprise-only > .menu__link::after { + content: 'ENT'; + display: inline-flex; + align-items: center; + justify-content: center; + font-size: 0.55rem; + font-weight: 700; + letter-spacing: 0.03em; + line-height: 1; + padding: 0.15em 0.4em; + margin-left: 0.75em; + border: 1.5px solid #2a9d8f; + border-radius: 999px; + color: #1a5c54; + flex-shrink: 0; +} + +.enterprise-only > .menu__link:hover::before { + content: 'Stacklok Enterprise feature'; + position: absolute; + left: 50%; + bottom: calc(100% + 6px); + transform: translateX(-50%); + padding: 0.3em 0.6em; + font-size: 0.7rem; + font-weight: 500; + line-height: 1.3; + white-space: nowrap; + color: #fff; + background: #1a5c54; + border-radius: 4px; + pointer-events: none; + z-index: 10; +} + +[data-theme='dark'] .enterprise-only > .menu__link::after { + color: #c8ece7; + border-color: #2a9d8f; +} + +[data-theme='dark'] .enterprise-only > .menu__link:hover::before { + background: #1a5c54; + color: #c8ece7; +} + /* Screenshot styling with subtle border */ .screenshot { border: 1px solid var(--ifm-table-border-color); diff --git a/src/theme/Admonition/Types.tsx b/src/theme/Admonition/Types.tsx new file mode 100644 index 00000000..3b701ba9 --- /dev/null +++ b/src/theme/Admonition/Types.tsx @@ -0,0 +1,46 @@ +import React, { type ReactNode } from 'react'; +import DefaultAdmonitionTypes from '@theme-original/Admonition/Types'; +import AdmonitionLayout from '@theme/Admonition/Layout'; + +const StacklokIcon = () => ( + +); + +interface EnterpriseAdmonitionProps { + children: ReactNode; + title?: string; + className?: string; +} + +function EnterpriseAdmonition(props: EnterpriseAdmonitionProps): ReactNode { + return ( + } + title={props.title ?? 'Stacklok Enterprise'} + className={`alert alert--enterprise ${props.className ?? ''}`} + > + {props.children} + + ); +} + +const AdmonitionTypes = { + ...DefaultAdmonitionTypes, + enterprise: EnterpriseAdmonition, +}; + +export default AdmonitionTypes; From fc69b4542c5f02a207b8319d0c975f34da90fd60 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:03:28 -0400 Subject: [PATCH 2/4] Add inline EnterpriseBadge component and reorganize theme preview EnterpriseBadge component for labeling individual enterprise features inline with text, headings, and lists. Enterprise constructs grouped into their own section on the theme preview page. Removed sidebar badge demo from the Enterprise page entry. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/theme-preview.mdx | 30 ++++++++++++++++++- eslint.config.mjs | 1 + sidebars.ts | 6 +--- src/components/EnterpriseBadge/index.tsx | 10 +++++++ .../EnterpriseBadge/styles.module.css | 20 +++++++++++++ src/theme/MDXComponents.tsx | 2 ++ 6 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 src/components/EnterpriseBadge/index.tsx create mode 100644 src/components/EnterpriseBadge/styles.module.css diff --git a/docs/theme-preview.mdx b/docs/theme-preview.mdx index c0c609a5..bc7a03dd 100644 --- a/docs/theme-preview.mdx +++ b/docs/theme-preview.mdx @@ -174,7 +174,13 @@ This is getting silly ::::: -Custom `:::enterprise` admonition for inline Enterprise upsell content. Uses the +## Enterprise constructs + +Components for presenting Stacklok Enterprise content inline with OSS docs. + +### Enterprise admonition + +Custom `:::enterprise` admonition for callout content within OSS pages. Uses the Stacklok symbol as the icon and a teal color palette distinct from the other admonition types. Supports custom titles via `:::enterprise[My title]`. @@ -188,6 +194,28 @@ integration to map IdP groups directly to ToolHive roles and policy sets. ::: +### Enterprise badge + +Inline `` component for labeling individual features or +capabilities within a page. Works next to headings, in lists, or inline with +text. + +#### Session pinning + +Sessions can be pinned to a specific node for the duration of a connection. + +- **Automatic failover** - connections are automatically + rerouted when a node becomes unavailable. +- **Manual failover** - connections can be manually rerouted by an + administrator. + +### Sidebar badge + +Enterprise-only pages can be marked with an `ENT` badge in the sidebar by adding +`className: 'enterprise-only'` to the sidebar item in `sidebars.ts`. The badge +includes a tooltip on hover. See "Stacklok Enterprise" in the sidebar for an +example. + ## Tables A standard Markdown table: diff --git a/eslint.config.mjs b/eslint.config.mjs index a7e1a248..8697d0a0 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -45,6 +45,7 @@ export default [ Tabs: 'readonly', TabItem: 'readonly', MCPMetadata: 'readonly', + EnterpriseBadge: 'readonly', }, }, }, diff --git a/sidebars.ts b/sidebars.ts index d1f2288b..e891b856 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -291,11 +291,7 @@ const sidebars: SidebarsConfig = { 'toolhive/reference/index', 'toolhive/reference/authz-policy-reference', 'toolhive/faq', - { - type: 'doc', - id: 'toolhive/enterprise', - className: 'enterprise-only', - }, + 'toolhive/enterprise', 'toolhive/support', 'toolhive/contributing', ], diff --git a/src/components/EnterpriseBadge/index.tsx b/src/components/EnterpriseBadge/index.tsx new file mode 100644 index 00000000..013c217b --- /dev/null +++ b/src/components/EnterpriseBadge/index.tsx @@ -0,0 +1,10 @@ +import React from 'react'; +import styles from './styles.module.css'; + +export default function EnterpriseBadge(): React.ReactNode { + return ( + + Enterprise + + ); +} diff --git a/src/components/EnterpriseBadge/styles.module.css b/src/components/EnterpriseBadge/styles.module.css new file mode 100644 index 00000000..ef302f83 --- /dev/null +++ b/src/components/EnterpriseBadge/styles.module.css @@ -0,0 +1,20 @@ +.badge { + display: inline-flex; + align-items: center; + font-size: 0.7rem; + font-weight: 600; + letter-spacing: 0.02em; + line-height: 1; + padding: 0.2em 0.6em; + border: 1.5px solid #2a9d8f; + border-radius: 6px; + color: #1a5c54; + vertical-align: middle; + margin-left: 0.4em; + white-space: nowrap; +} + +:global([data-theme='dark']) .badge { + color: #c8ece7; + border-color: #2a9d8f; +} diff --git a/src/theme/MDXComponents.tsx b/src/theme/MDXComponents.tsx index aef9f3e0..1db71f66 100644 --- a/src/theme/MDXComponents.tsx +++ b/src/theme/MDXComponents.tsx @@ -10,6 +10,7 @@ import MDXComponents from '@theme-original/MDXComponents'; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; import MCPMetadata from '@site/src/components/MCPMetadata'; +import EnterpriseBadge from '@site/src/components/EnterpriseBadge'; export default { // Reusing the default mapping @@ -18,4 +19,5 @@ export default { Tabs, TabItem, MCPMetadata, + EnterpriseBadge, }; From ebd1200821a0224d343195bb6ec0de84f6af34ff Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:10:51 -0400 Subject: [PATCH 3/4] Show sidebar ENT tooltip on keyboard focus Co-Authored-By: Claude Opus 4.6 (1M context) --- src/css/custom.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/css/custom.css b/src/css/custom.css index 720dc94e..151fab84 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -417,7 +417,8 @@ details summary:hover { flex-shrink: 0; } -.enterprise-only > .menu__link:hover::before { +.enterprise-only > .menu__link:hover::before, +.enterprise-only > .menu__link:focus-visible::before { content: 'Stacklok Enterprise feature'; position: absolute; left: 50%; @@ -440,7 +441,8 @@ details summary:hover { border-color: #2a9d8f; } -[data-theme='dark'] .enterprise-only > .menu__link:hover::before { +[data-theme='dark'] .enterprise-only > .menu__link:hover::before, +[data-theme='dark'] .enterprise-only > .menu__link:focus-visible::before { background: #1a5c54; color: #c8ece7; } From 76292a7c8d578c3acb31de5053e0a10a73d68354 Mon Sep 17 00:00:00 2001 From: Dan Barr <6922515+danbarr@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:16:53 -0400 Subject: [PATCH 4/4] Document enterprise constructs in CLAUDE.md and review skill Add enterprise content constructs section to CLAUDE.md with usage guidance for all three patterns. Update docs-review skill to check for correct enterprise construct usage. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/skills/docs-review/SKILL.md | 1 + AGENTS.md | 38 ++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/.claude/skills/docs-review/SKILL.md b/.claude/skills/docs-review/SKILL.md index 61a37a5c..12060b5a 100644 --- a/.claude/skills/docs-review/SKILL.md +++ b/.claude/skills/docs-review/SKILL.md @@ -51,6 +51,7 @@ Perform critical editorial reviews as a tech writer / copyeditor, focusing on cl - **Heading count**: 20+ headings signals over-segmentation; consolidate - **Information flow**: Conceptual content (trade-offs, when to use) should come before implementation details, not after - **Admonition weight**: Tips, notes, and warnings should be supplementary. If an admonition contains primary feature documentation (full YAML examples, the only explanation of a field or concept), it should be promoted to a proper section or its own page. A good test: if this admonition is the only place a feature is documented, it's not a tip - it's a section that needs a heading and ToC visibility. +- **Enterprise construct usage**: Three constructs exist for enterprise content - check they're used correctly. `:::enterprise` admonitions are for callout blocks (2-4 sentences, max 1-2 per page). `` is for inline feature labels next to headings or list items. `className: 'enterprise-only'` in the sidebar is for enterprise-only pages. Flag misuse: enterprise admonitions used for single-feature labels (use `` instead), badge used on entire page descriptions (use the admonition instead), or excessive enterprise admonitions on a single page. - **Diataxis alignment**: Don't mix tutorials, how-tos, reference, and concepts in one doc without clear separation ### LLM-Generated Content Patterns diff --git a/AGENTS.md b/AGENTS.md index 3c3bca8a..adc647e8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -263,7 +263,43 @@ This website is built using Docusaurus, which has some specific requirements and - Titles are added using the `title="..."` attribute in the opening code fence. - Line highlights are added using comma-separated `{number}` or `{start-end}` ranges in the opening code fence, or `highlight-next-line`, `highlight-start`, and `highlight-end` comments within the code block. - Use admonitions for notes, tips, warnings, and other annotations. This provides a consistent look and feel across the site. - - Use the `:::type` syntax to define the admonition type: `note`, `tip`, `info`, `warning`, or `danger`. Use square brackets to add a custom title, e.g. `:::info[Title]`. Add empty lines around the start and end directives. + - Use the `:::type` syntax to define the admonition type: `note`, `tip`, `info`, `warning`, `danger`, or `enterprise`. Use square brackets to add a custom title, e.g. `:::info[Title]`. Add empty lines around the start and end directives. + - The `:::enterprise` admonition is for Stacklok Enterprise content only - see "Enterprise content constructs" below. - Place images in `static/img` using WebP, PNG, or SVG format. - Use the `ThemedImage` component to provide both light and dark mode screenshots for apps/UIs that support both. Typically used with the `useBaseUrl` hook to construct the image paths. Both require import statements. - Use the `Tabs` and `TabItem` components to create tabbed content sections. These are in the global scope and do not require imports. +- Use the `EnterpriseBadge` component to label individual features or capabilities as enterprise-only. This is in the global scope and does not require imports. See "Enterprise content constructs" below. + +### Enterprise content constructs + +Three constructs are available for presenting Stacklok Enterprise content inline with OSS documentation. Use the right one for the context: + +**`:::enterprise` admonition** - for callout content within OSS pages, typically 2-4 sentences describing an Enterprise capability with a link to the Enterprise landing page. Use when Enterprise adds a meaningful capability to the topic being documented. Don't overuse - one per page is typical, two is the practical maximum. + +```mdx +:::enterprise + +Stacklok Enterprise includes turnkey integrations for common identity providers. Instead of manually configuring OIDC, use the built-in Okta or Entra ID integration to map IdP groups directly to ToolHive roles and policy sets. + +[Learn more about Stacklok Enterprise](/toolhive/enterprise). + +::: +``` + +**``** - inline label for tagging individual features, capabilities, or configuration options as enterprise-only. Works next to headings, in lists, or inline with text. Use when a specific feature within a broader page is enterprise-only. + +```mdx +### Session pinning + +- **Automatic failover** - connections are automatically rerouted when a node becomes unavailable. +``` + +**`className: 'enterprise-only'` sidebar badge** - for marking enterprise-only pages in the sidebar navigation. Applied in `sidebars.ts`, not in the page itself. Renders a small "ENT" pill badge with a tooltip on hover. + +```ts title="sidebars.ts" +{ + type: 'doc', + id: 'toolhive/guides-enterprise/config-server', + className: 'enterprise-only', +} +```