From 0aed7a8cefbe38627abb3dac39cc3b8cdbc30984 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 3 Jun 2026 23:01:23 +0000 Subject: [PATCH 01/21] add cc to build --- unified-doc/build-docs.sh | 23 +++++++++++++++++++++-- unified-doc/docusaurus.config.ts | 25 ++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index 80d5b34..1046e11 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -17,6 +17,7 @@ # --zlan-branch=BRANCH Branch for netfoundry/zlan (default: main) # --platform-branch=BRANCH Branch for netfoundry/platform-doc (default: main) # --data-connector-branch=BRANCH Branch for netfoundry/nf-data-connector (default: main) +# --customer-connect-branch=BRANCH Branch for netfoundry/customer-connect-docs (default: main) # --clean Wipe _remotes and .docusaurus cache before building # --lint-only Run lint checks only; skip build # --qualifier=VALUE Append VALUE to output dir (e.g. --qualifier=-preview -> build-preview) @@ -31,10 +32,12 @@ # BB_REPO_TOKEN_ONPREM Bitbucket token for k8s-on-prem-installations (falls back to SSH) # BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for platform-doc (falls back to SSH) # BB_REPO_TOKEN_DATA_CONNECTOR Bitbucket token for nf-data-connector (falls back to SSH) +# BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for customer-connect-docs (falls back to SSH) # BB_USERNAME Bitbucket username (default: x-token-auth) # DOCUSAURUS_BUILD_MASK Hex bitmask: 0x1=openziti 0x2=frontdoor 0x4=selfhosted # 0x8=zrok 0x10=zlan 0x20=platform -# 0x40=data-connector 0xFF=all (default: 0xFF) +# 0x40=data-connector 0x80=llm-gateway 0x100=mcp-gateway +# 0x200=customer-connect 0x3FF=all (default: 0x3FF) # DOCUSAURUS_PUBLISH_ENV Set to 'prod' to use production Algolia index # NO_MINIFY Set to any value to pass --no-minify to Docusaurus # IS_VERCEL Set to 'true' on Vercel preview deployments @@ -62,6 +65,7 @@ BRANCH_SELFHOSTED="main" BRANCH_ZLAN="main" BRANCH_PLATFORM="main" BRANCH_DATA_CONNECTOR="main" +BRANCH_CUSTOMER_CONNECT="main" usage() { sed -n '/^# USAGE/,/^# =====/{ /^# =====/d; s/^# \{0,1\}//; p }' "$0" @@ -76,6 +80,7 @@ while [[ $# -gt 0 ]]; do --zlan-branch=*) BRANCH_ZLAN="${1#*=}"; shift ;; --platform-branch=*) BRANCH_PLATFORM="${1#*=}"; shift ;; --data-connector-branch=*) BRANCH_DATA_CONNECTOR="${1#*=}"; shift ;; + --customer-connect-branch=*) BRANCH_CUSTOMER_CONNECT="${1#*=}"; shift ;; --ziti-doc-branch) BRANCH_ZITI_DOC="${2:?--ziti-doc-branch requires a value}"; shift 2 ;; --zrok-branch) BRANCH_ZROK="${2:?--zrok-branch requires a value}"; shift 2 ;; --frontdoor-branch) BRANCH_FRONTDOOR="${2:?--frontdoor-branch requires a value}"; shift 2 ;; @@ -83,6 +88,7 @@ while [[ $# -gt 0 ]]; do --zlan-branch) BRANCH_ZLAN="${2:?--zlan-branch requires a value}"; shift 2 ;; --platform-branch) BRANCH_PLATFORM="${2:?--platform-branch requires a value}"; shift 2 ;; --data-connector-branch) BRANCH_DATA_CONNECTOR="${2:?--data-connector-branch requires a value}"; shift 2 ;; + --customer-connect-branch) BRANCH_CUSTOMER_CONNECT="${2:?--customer-connect-branch requires a value}"; shift 2 ;; --clean) CLEAN=1; shift ;; --lint-only) LINT_ONLY=1; shift ;; -h|--help) usage; exit 0 ;; @@ -109,6 +115,7 @@ echo " BRANCH_SELFHOSTED='$BRANCH_SELFHOSTED'" echo " BRANCH_ZLAN='$BRANCH_ZLAN'" echo " BRANCH_PLATFORM='$BRANCH_PLATFORM'" echo " BRANCH_DATA_CONNECTOR='$BRANCH_DATA_CONNECTOR'" +echo " BRANCH_CUSTOMER_CONNECT='$BRANCH_CUSTOMER_CONNECT'" echo " CLEAN=$CLEAN" echo " IS_VERCEL='${IS_VERCEL:-}'" echo " node: $(node --version 2>/dev/null || echo 'not found')" @@ -186,6 +193,16 @@ clone_or_update() { echo "πŸ”‘ Using SSH for nf-data-connector" >&2 fi ;; + *customer-connect-docs*) + if [ -n "${BB_REPO_TOKEN_PLATFORM_DOC:-}" ]; then + local bb_user="${BB_USERNAME:-x-token-auth}" + url="https://${bb_user}:${BB_REPO_TOKEN_PLATFORM_DOC}@bitbucket.org/netfoundry/customer-connect-docs.git" + echo "πŸ”‘ Using BB_REPO_TOKEN_PLATFORM_DOC token for customer-connect-docs" >&2 + else + url="git@bitbucket.org:netfoundry/customer-connect-docs.git" + echo "πŸ”‘ Using SSH for customer-connect-docs" >&2 + fi + ;; esac if [ -d "$target/.git" ]; then @@ -263,6 +280,7 @@ lint_docs() { "${script_dir}/_remotes/openziti/docusaurus/docs" "${script_dir}/_remotes/platform/docusaurus/docs" "${script_dir}/_remotes/data-connector/docusaurus/docs" + "${script_dir}/_remotes/customer-connect/docusaurus/docs" ) # 2. VERIFY FOLDERS @@ -393,7 +411,8 @@ clone_or_update "https://github.com/openziti/ziti-doc.git" clone_or_update "https://github.com/netfoundry/zlan.git" zlan "$BRANCH_ZLAN" clone_or_update "https://github.com/openziti/zrok.git" zrok "$BRANCH_ZROK" clone_or_update "https://bitbucket.org/netfoundry/platform-doc.git" platform "$BRANCH_PLATFORM" -clone_or_update "https://bitbucket.org/netfoundry/nf-data-connector.git" data-connector "$BRANCH_DATA_CONNECTOR" +clone_or_update "https://bitbucket.org/netfoundry/nf-data-connector.git" data-connector "$BRANCH_DATA_CONNECTOR" +clone_or_update "https://bitbucket.org/netfoundry/customer-connect-docs.git" customer-connect "$BRANCH_CUSTOMER_CONNECT" echo "Cleaning stale build artifacts from remotes..." find "$script_dir/_remotes" -type d \( -path "*/docusaurus/build" -o -path "*/docusaurus/.docusaurus" -o -path "*/website/build" -o -path "*/website/.docusaurus" \) -exec rm -rf {} + 2>/dev/null || true diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 1eb97e3..7d20acc 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -26,6 +26,7 @@ import {onpremRedirects} from "./_remotes/selfhosted/docusaurus/docusaurus-plugi import {platformDocsPluginConfig, platformRedirects} from "./_remotes/platform/docusaurus/docusaurus-plugin-platform-docs.ts"; import {openzitiDocsPluginConfig, openzitiRedirects} from "./_remotes/openziti/docusaurus/docusaurus-plugin-openziti-docs.ts"; import {dataconnectorDocsPluginConfig} from "./_remotes/data-connector/docusaurus/docusaurus-plugin-dataconnector-docs.ts"; +import {customerConnectDocsPluginConfig} from "./_remotes/customer-connect/docusaurus/docusaurus-plugin-customer-connect-docs.ts"; // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const frontdoor = `./_remotes/frontdoor`; @@ -35,6 +36,7 @@ const zrokRoot = `./_remotes/zrok/website`; const zlan = `./_remotes/zlan`; const platform = `./_remotes/platform`; const dataConnector = `./_remotes/data-connector`; +const customerConnect = `./_remotes/customer-connect`; const llmGateway = `./docs/llm-gateway`; const mcpGateway = `./docs/mcp-gateway`; @@ -48,7 +50,7 @@ function routeBase(name: string) { return isVercel ? `docs/${name}` : name; } -const buildMask = parseInt(process.env.DOCUSAURUS_BUILD_MASK ?? "0x1FF", 16); +const buildMask = parseInt(process.env.DOCUSAURUS_BUILD_MASK ?? "0x3FF", 16); const BUILD_FLAGS = { NONE: 0x0, @@ -59,8 +61,9 @@ const BUILD_FLAGS = { ZLAN: 0x10, PLATFORM: 0x20, DATA_CONNECTOR: 0x40, - LLM_GATEWAY: 0x80, - MCP_GATEWAY: 0x100, + LLM_GATEWAY: 0x80, + MCP_GATEWAY: 0x100, + CUSTOMER_CONNECT: 0x200, }; function build(flag: number) { @@ -121,6 +124,7 @@ const REMARK_MAPPINGS = [ { from: '@dataconnectordocs', to: `${docsBase}dataconnector`}, { from: '@llmgatewaydocs', to: `${docsBase}llm-gateway`}, { from: '@mcpgatewaydocs', to: `${docsBase}mcp-gateway`}, + { from: '@customerconnectdocs', to: `${docsBase}customer-connect`}, { from: '@static', to: docsBase}, { from: '/openziti', to: `${docsBase}${routeBase('openziti')}` }, { from: '/frontdoor', to: `${docsBase}${routeBase('frontdoor')}` }, @@ -295,6 +299,7 @@ const config: Config = { '_remotes/openziti/docusaurus/static/', '_remotes/zlan/docusaurus/static/', '_remotes/platform/docusaurus/static/', + '_remotes/customer-connect/docusaurus/static/', `${zrokRoot}/static/`, `${zrokRoot}/docs/images` ], @@ -353,6 +358,7 @@ const config: Config = { '@staticdir': path.resolve(__dirname, `docusaurus/static`), '@platform': path.resolve(__dirname, `${platform}/docusaurus`), '@dataconnector': path.resolve(__dirname, `${dataConnector}/docusaurus`), + '@customerconnectdocs': path.resolve(__dirname, `${customerConnect}/docusaurus`), }, }, module: { @@ -376,6 +382,7 @@ const config: Config = { build(BUILD_FLAGS.ZROK) && ['@docusaurus/plugin-content-pages',{id: `zrok-pages`, path: `${zrokRoot}/src/pages`, routeBasePath: `/${routeBase('zrok')}`}], build(BUILD_FLAGS.PLATFORM) && ['@docusaurus/plugin-content-pages',{id: `platform-pages`, path: `${platform}/docusaurus/src/pages`, routeBasePath: `/${routeBase('platform')}`}], build(BUILD_FLAGS.DATA_CONNECTOR) && ['@docusaurus/plugin-content-pages',{id: `dataconnector-pages`, path: `${dataConnector}/docusaurus/src/pages`, routeBasePath: `/${routeBase('dataconnector')}`}], + build(BUILD_FLAGS.CUSTOMER_CONNECT) && ['@docusaurus/plugin-content-pages',{id: `customer-connect-pages`, path: `${customerConnect}/docusaurus/src/pages`, routeBasePath: `/${routeBase('customer-connect')}`}], build(BUILD_FLAGS.ZROK) && extendDocsPlugins(zrokDocsPluginConfig(zrokRoot, REMARK_MAPPINGS, routeBase('zrok'))), build(BUILD_FLAGS.SELFHOSTED) && [ '@docusaurus/plugin-content-docs', @@ -441,6 +448,11 @@ const config: Config = { routeBase('dataconnector'), ), ), + build(BUILD_FLAGS.CUSTOMER_CONNECT) && customerConnectDocsPluginConfig( + `${customerConnect}/docusaurus`, + REMARK_MAPPINGS, + routeBase('customer-connect'), + ), build(BUILD_FLAGS.LLM_GATEWAY) && [ '@docusaurus/plugin-content-docs', { @@ -502,6 +514,13 @@ const config: Config = { showNavLink: false, configuration: {url: `${docsBase}console-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, } as ScalarOptions], + build(BUILD_FLAGS.CUSTOMER_CONNECT) && ['@scalar/docusaurus', { + id: 'customer-connect-api', + label: 'API reference', + route: `/${routeBase('customer-connect')}/api-guides/openapi-reference`, + showNavLink: false, + configuration: {url: `${docsBase}customer-connect-api-spec.yaml`, hideClientButton: true, hideTestRequestButton: true, searchHotKey: 'i'}, + } as ScalarOptions], build(BUILD_FLAGS.FRONTDOOR) && ['@scalar/docusaurus', { id: 'frontdoor-api', label: 'API reference', From 40f67b3b97a0cec688823147df50f3227f23db4b Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 3 Jun 2026 23:13:28 +0000 Subject: [PATCH 02/21] fix token --- unified-doc/build-docs.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index 1046e11..9728423 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -32,7 +32,7 @@ # BB_REPO_TOKEN_ONPREM Bitbucket token for k8s-on-prem-installations (falls back to SSH) # BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for platform-doc (falls back to SSH) # BB_REPO_TOKEN_DATA_CONNECTOR Bitbucket token for nf-data-connector (falls back to SSH) -# BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for customer-connect-docs (falls back to SSH) +# BB_REPO_TOKEN_CUSTOMER_CONNECT Bitbucket token for customer-connect-docs (falls back to SSH) # BB_USERNAME Bitbucket username (default: x-token-auth) # DOCUSAURUS_BUILD_MASK Hex bitmask: 0x1=openziti 0x2=frontdoor 0x4=selfhosted # 0x8=zrok 0x10=zlan 0x20=platform @@ -194,10 +194,10 @@ clone_or_update() { fi ;; *customer-connect-docs*) - if [ -n "${BB_REPO_TOKEN_PLATFORM_DOC:-}" ]; then + if [ -n "${BB_REPO_TOKEN_CUSTOMER_CONNECT:-}" ]; then local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_PLATFORM_DOC}@bitbucket.org/netfoundry/customer-connect-docs.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_PLATFORM_DOC token for customer-connect-docs" >&2 + url="https://${bb_user}:${BB_REPO_TOKEN_CUSTOMER_CONNECT}@bitbucket.org/netfoundry/customer-connect-docs.git" + echo "πŸ”‘ Using BB_REPO_TOKEN_CUSTOMER_CONNECT token" >&2 else url="git@bitbucket.org:netfoundry/customer-connect-docs.git" echo "πŸ”‘ Using SSH for customer-connect-docs" >&2 From ccb2da504f3a53368eaadeb8a018b2bda16f04a2 Mon Sep 17 00:00:00 2001 From: Nico Alba Date: Wed, 3 Jun 2026 23:20:52 +0000 Subject: [PATCH 03/21] update branch --- unified-doc/build-docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index 9728423..b9b9a3a 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -65,7 +65,7 @@ BRANCH_SELFHOSTED="main" BRANCH_ZLAN="main" BRANCH_PLATFORM="main" BRANCH_DATA_CONNECTOR="main" -BRANCH_CUSTOMER_CONNECT="main" +BRANCH_CUSTOMER_CONNECT="add-docs" usage() { sed -n '/^# USAGE/,/^# =====/{ /^# =====/d; s/^# \{0,1\}//; p }' "$0" From 6b0b26e3f5398232b043aa4ab2ee56d54f14131a Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 22 Jul 2026 15:38:52 -0400 Subject: [PATCH 04/21] update from add-docs to main --- unified-doc/build-docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index b9b9a3a..9728423 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -65,7 +65,7 @@ BRANCH_SELFHOSTED="main" BRANCH_ZLAN="main" BRANCH_PLATFORM="main" BRANCH_DATA_CONNECTOR="main" -BRANCH_CUSTOMER_CONNECT="add-docs" +BRANCH_CUSTOMER_CONNECT="main" usage() { sed -n '/^# USAGE/,/^# =====/{ /^# =====/d; s/^# \{0,1\}//; p }' "$0" From 973abc6b0e4ce8710f54ff39e4ab3ac9fcb8e897 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Wed, 22 Jul 2026 16:37:38 -0400 Subject: [PATCH 05/21] use add-docs again --- unified-doc/build-docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index 9728423..b9b9a3a 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -65,7 +65,7 @@ BRANCH_SELFHOSTED="main" BRANCH_ZLAN="main" BRANCH_PLATFORM="main" BRANCH_DATA_CONNECTOR="main" -BRANCH_CUSTOMER_CONNECT="main" +BRANCH_CUSTOMER_CONNECT="add-docs" usage() { sed -n '/^# USAGE/,/^# =====/{ /^# =====/d; s/^# \{0,1\}//; p }' "$0" From f484e6b2c3819e1e0eb3a3ace167f3265d2297f2 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 07:40:48 -0400 Subject: [PATCH 06/21] build-docs.mjs refactor + picker consumer bump to theme 0.17.0 --- unified-doc/build-docs.mjs | 585 +++++++++++++++++++++++++++++++ unified-doc/build-docs.ps1 | 395 +++------------------ unified-doc/build-docs.sh | 465 +----------------------- unified-doc/docusaurus.config.ts | 6 +- unified-doc/package.json | 2 +- unified-doc/yarn.lock | 8 +- 6 files changed, 645 insertions(+), 816 deletions(-) create mode 100644 unified-doc/build-docs.mjs diff --git a/unified-doc/build-docs.mjs b/unified-doc/build-docs.mjs new file mode 100644 index 0000000..d2fcce6 --- /dev/null +++ b/unified-doc/build-docs.mjs @@ -0,0 +1,585 @@ +#!/usr/bin/env node +// ============================================================================= +// build-docs.mjs β€” Build the unified NetFoundry documentation site. +// +// This is the SINGLE source of truth for the unified-doc build orchestration. +// build-docs.sh and build-docs.ps1 are thin platform shims that call this file; +// do not reimplement build logic in them. +// +// Clones (or updates) all product doc repos into _remotes/, runs lint checks, +// builds SDK reference docs via ziti-doc's gendoc script, then runs a Docusaurus +// production build. +// +// USAGE +// node build-docs.mjs [OPTIONS] +// +// OPTIONS +// --ziti-doc-branch=BRANCH Branch for openziti/ziti-doc (default: main) +// --zrok-branch=BRANCH Branch for openziti/zrok (default: main) +// --frontdoor-branch=BRANCH Branch for netfoundry/zrok-connector (default: develop) +// --selfhosted-branch=BRANCH Branch for netfoundry/k8s-on-prem-installations (default: main) +// --zlan-branch=BRANCH Branch for netfoundry/zlan (default: main) +// --platform-branch=BRANCH Branch for netfoundry/platform-doc (default: main) +// --data-connector-branch=BRANCH Branch for netfoundry/nf-data-connector (default: main) +// --customer-connect-branch=BRANCH Branch for netfoundry/customer-connect-docs (default: main) +// --clean Wipe _remotes and .docusaurus cache before building +// --lint-only Run lint checks only; skip build +// --qualifier=VALUE Append VALUE to output dir (e.g. --qualifier=-preview -> build-preview) +// -l (gendoc) Skip linked doc generation (doxygen/wget) +// -g (gendoc) Skip git clones inside gendoc +// -c (gendoc) Skip clean steps inside gendoc +// -h, --help Show this help and exit +// +// ENVIRONMENT VARIABLES +// GH_ZITI_CI_REPO_ACCESS_PAT GitHub PAT for ziti-doc and zlan (falls back to SSH) +// BB_REPO_TOKEN_FRONTDOOR Bitbucket token for zrok-connector (falls back to SSH) +// BB_REPO_TOKEN_ONPREM Bitbucket token for k8s-on-prem-installations (falls back to SSH) +// BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for platform-doc (falls back to SSH) +// BB_REPO_TOKEN_DATA_CONNECTOR Bitbucket token for nf-data-connector (falls back to SSH) +// BB_REPO_TOKEN_CUSTOMER_CONNECT Bitbucket token for customer-connect-docs (falls back to SSH) +// BB_USERNAME Bitbucket username (default: x-token-auth) +// DOCUSAURUS_BUILD_MASK Hex bitmask: 0x1=openziti 0x2=frontdoor 0x4=selfhosted +// 0x8=zrok 0x10=zlan 0x20=platform +// 0x40=data-connector 0x80=llm-gateway 0x100=mcp-gateway +// 0x200=customer-connect 0x3FF=all (config default: 0x3FF) +// DOCUSAURUS_PUBLISH_ENV Set to 'prod' to use production Algolia index +// NO_MINIFY Set to any value to pass --no-minify to Docusaurus +// IS_VERCEL Set to 'true' on Vercel preview deployments +// +// EXAMPLES +// node build-docs.mjs --ziti-doc-branch=my.branch.name +// DOCUSAURUS_BUILD_MASK=0x1 node build-docs.mjs --ziti-doc-branch=my.branch.name +// node build-docs.mjs --clean --lint-only +// node build-docs.mjs --qualifier=-preview -l +// ============================================================================= + +import { spawnSync } from "node:child_process"; +import { + existsSync, readdirSync, rmSync, mkdirSync, cpSync, writeFileSync, +} from "node:fs"; +import { join, dirname, basename } from "node:path"; +import { fileURLToPath } from "node:url"; + +const isWin = process.platform === "win32"; +const GIT = "git"; +const YARN = isWin ? "yarn.cmd" : "yarn"; +const VALE = "vale"; +const MDLINT = isWin ? "markdownlint.cmd" : "markdownlint"; + +// On Windows, markdownlint runs through cmd.exe (~8191-char command-line cap), +// so lint files in small batches there; larger batches elsewhere. +const LINT_BATCH = isWin ? 50 : 200; + +const scriptDir = dirname(fileURLToPath(import.meta.url)); +const remotesDir = join(scriptDir, "_remotes"); + +// ============================================================================= +// SMALL PROCESS / FS HELPERS +// ============================================================================= + +// Node on Windows refuses to spawnSync a .cmd/.bat without a shell (EINVAL, since +// the CVE-2024-27980 fix). Route those through cmd.exe and quote args ourselves β€” +// shell:true does NOT quote array args for us. Non-.cmd/.exe commands and every +// platform other than Windows go straight through. +function spawnCompat(cmd, args, opts = {}) { + if (isWin && /\.(cmd|bat)$/i.test(cmd)) { + const quoted = args.map((a) => + /[\s"&|<>^()%!]/.test(a) ? `"${a.replace(/"/g, '""')}"` : a, + ); + return spawnSync(cmd, quoted, { ...opts, shell: true }); + } + return spawnSync(cmd, args, opts); +} + +// Run a command, stream its output, and abort the whole build on failure +// (mirrors `set -euo pipefail`). +function run(cmd, args, opts = {}) { + const r = spawnCompat(cmd, args, { stdio: "inherit", env: process.env, ...opts }); + if (r.error) { + console.error(`ERROR: failed to run '${cmd}': ${r.error.message}`); + process.exit(1); + } + if (r.status !== 0) { + console.error(`ERROR: '${cmd}' exited with code ${r.status}`); + process.exit(r.status ?? 1); + } + return r; +} + +// Run a command and capture stdout/stderr without aborting. +function capture(cmd, args, opts = {}) { + return spawnCompat(cmd, args, { + encoding: "utf8", env: process.env, maxBuffer: 64 * 1024 * 1024, ...opts, + }); +} + +// Is a command available on PATH? +function has(cmd) { + const r = spawnCompat(cmd, ["--version"], { stdio: "ignore" }); + return !r.error && r.status === 0; +} + +function chunk(arr, n) { + const out = []; + for (let i = 0; i < arr.length; i += n) out.push(arr.slice(i, i + n)); + return out; +} + +// ============================================================================= +// ARGUMENT PARSING (mirror of build-docs.sh) +// ============================================================================= + +const USAGE = `Usage: node build-docs.mjs [OPTIONS] β€” see header of build-docs.mjs for full docs.`; + +const branches = { + zitiDoc : "main", + zrok : "main", + frontdoor : "develop", + selfhosted : "main", + zlan : "main", + platform : "main", + dataConnector : "main", + customerConnect: "add-docs", +}; +const BRANCH_FLAG = { + "--ziti-doc-branch": "zitiDoc", + "--zrok-branch": "zrok", + "--frontdoor-branch": "frontdoor", + "--selfhosted-branch": "selfhosted", + "--zlan-branch": "zlan", + "--platform-branch": "platform", + "--data-connector-branch": "dataConnector", + "--customer-connect-branch": "customerConnect", +}; + +let clean = false; +let lintOnly = false; +let qualifier = ""; +const otherFlags = []; // forwarded verbatim to gendoc (-l/-g/-c/...) + +const argv = process.argv.slice(2); +for (let i = 0; i < argv.length; i++) { + const a = argv[i]; + + const need = (flag) => { + const v = argv[++i]; + if (v === undefined) { + console.error(`Error: ${flag} requires a value`); + process.exit(1); + } + return v; + }; + + let handled = false; + for (const [flag, key] of Object.entries(BRANCH_FLAG)) { + if (a === flag) { branches[key] = need(flag); handled = true; break; } + if (a.startsWith(`${flag}=`)) { branches[key] = a.slice(flag.length + 1); handled = true; break; } + } + if (handled) continue; + + if (a === "--clean") { clean = true; continue; } + if (a === "--lint-only") { lintOnly = true; continue; } + if (a === "-h" || a === "--help") { console.log(USAGE); process.exit(0); } + if (a === "--qualifier") { qualifier = need("--qualifier"); continue; } + if (a.startsWith("--qualifier=")) { qualifier = a.slice("--qualifier=".length); continue; } + if (a.startsWith("-")) { otherFlags.push(a); continue; } // gendoc passthrough + // non-dash extra args are ignored, matching build-docs.sh +} + +// ============================================================================= +// BUILD CONFIGURATION BANNER +// ============================================================================= + +const line = "========================================"; +console.log(line); +console.log("BUILD CONFIGURATION"); +console.log(line); +console.log(` BRANCH_ZITI_DOC='${branches.zitiDoc}'`); +console.log(` BRANCH_ZROK='${branches.zrok}'`); +console.log(` BRANCH_FRONTDOOR='${branches.frontdoor}'`); +console.log(` BRANCH_SELFHOSTED='${branches.selfhosted}'`); +console.log(` BRANCH_ZLAN='${branches.zlan}'`); +console.log(` BRANCH_PLATFORM='${branches.platform}'`); +console.log(` BRANCH_DATA_CONNECTOR='${branches.dataConnector}'`); +console.log(` BRANCH_CUSTOMER_CONNECT='${branches.customerConnect}'`); +console.log(` CLEAN=${clean ? 1 : 0}`); +console.log(` IS_VERCEL='${process.env.IS_VERCEL ?? ""}'`); +console.log(` node: ${process.version}`); +console.log(` yarn: ${capture(YARN, ["--version"]).stdout?.trim() || "not found"}`); +console.log(line); + +// ============================================================================= +// clone_or_update +// ============================================================================= + +// Rewrite a public https URL into an authenticated one when the matching token +// env var is set; otherwise fall back to SSH. Mirrors the case block in .sh. +function authUrl(url) { + const bbUser = process.env.BB_USERNAME || "x-token-auth"; + const gh = (path, token) => `https://x-access-token:${token}@github.com/${path}`; + const bb = (path, token) => `https://${bbUser}:${token}@bitbucket.org/${path}`; + + if (url.includes("zlan")) { + if (process.env.GH_ZITI_CI_REPO_ACCESS_PAT) { + console.error("πŸ”‘ Using GH_ZITI_CI_REPO_ACCESS_PAT token for zlan"); + return gh("netfoundry/zlan.git", process.env.GH_ZITI_CI_REPO_ACCESS_PAT); + } + console.error("πŸ”‘ Using SSH for zlan"); + return "git@github.com:netfoundry/zlan.git"; + } + if (url.includes("k8s-on-prem-installations")) { + if (process.env.BB_REPO_TOKEN_ONPREM) { + console.error("πŸ”‘ Using BB_REPO_TOKEN_ONPREM token"); + return bb("netfoundry/k8s-on-prem-installations.git", process.env.BB_REPO_TOKEN_ONPREM); + } + console.error("πŸ”‘ Using SSH for self-hosted"); + return "git@bitbucket.org:netfoundry/k8s-on-prem-installations.git"; + } + if (url.includes("zrok-connector")) { + if (process.env.BB_REPO_TOKEN_FRONTDOOR) { + console.error("πŸ”‘ Using BB_REPO_TOKEN_FRONTDOOR token"); + return bb("netfoundry/zrok-connector.git", process.env.BB_REPO_TOKEN_FRONTDOOR); + } + console.error("πŸ”‘ Using SSH for frontdoor"); + return "git@bitbucket.org:netfoundry/zrok-connector.git"; + } + if (url.includes("ziti-doc")) { + if (process.env.GH_ZITI_CI_REPO_ACCESS_PAT) { + console.error("πŸ”‘ Using GH_ZITI_CI_REPO_ACCESS_PAT token for ziti-doc"); + return gh("openziti/ziti-doc.git", process.env.GH_ZITI_CI_REPO_ACCESS_PAT); + } + console.error("πŸ”‘ Using SSH for ziti-doc"); + return "git@github.com:openziti/ziti-doc.git"; + } + if (url.includes("platform-doc")) { + if (process.env.BB_REPO_TOKEN_PLATFORM_DOC) { + console.error("πŸ”‘ Using BB_REPO_TOKEN_PLATFORM_DOC token"); + return bb("netfoundry/platform-doc.git", process.env.BB_REPO_TOKEN_PLATFORM_DOC); + } + console.error("πŸ”‘ Using SSH for platform-doc"); + return "git@bitbucket.org:netfoundry/platform-doc.git"; + } + if (url.includes("nf-data-connector")) { + if (process.env.BB_REPO_TOKEN_DATA_CONNECTOR) { + console.error("πŸ”‘ Using BB_REPO_TOKEN_DATA_CONNECTOR token"); + return bb("netfoundry/nf-data-connector.git", process.env.BB_REPO_TOKEN_DATA_CONNECTOR); + } + console.error("πŸ”‘ Using SSH for nf-data-connector"); + return "git@bitbucket.org:netfoundry/nf-data-connector.git"; + } + if (url.includes("customer-connect-docs")) { + if (process.env.BB_REPO_TOKEN_CUSTOMER_CONNECT) { + console.error("πŸ”‘ Using BB_REPO_TOKEN_CUSTOMER_CONNECT token"); + return bb("netfoundry/customer-connect-docs.git", process.env.BB_REPO_TOKEN_CUSTOMER_CONNECT); + } + console.error("πŸ”‘ Using SSH for customer-connect-docs"); + return "git@bitbucket.org:netfoundry/customer-connect-docs.git"; + } + return url; // public (e.g. openziti/zrok) β€” no auth needed +} + +function redact(url) { + return url.replace(/:\/\/[^@]+@/, "://[REDACTED]@"); +} + +function failWithBranches(branch, url) { + console.log(`❌ Branch '${branch}' not found in ${redact(url)}`); + console.log("πŸ‘‰ Available branches:"); + const ls = capture(GIT, ["ls-remote", "--heads", url]); + for (const l of (ls.stdout || "").split("\n")) { + const ref = l.split(/\s+/)[1]; + if (ref) console.log(ref.replace("refs/heads/", "")); + } + process.exit(1); +} + +function cloneOrUpdate(rawUrl, dest, branch = "main") { + const target = join(remotesDir, dest); + const url = authUrl(rawUrl); + + if (existsSync(join(target, ".git"))) { + console.log(`Updating '${dest}' @ '${branch}'...`); + if (capture(GIT, ["-C", target, "remote", "set-url", "origin", url]).status !== 0) { + capture(GIT, ["-C", target, "remote", "add", "origin", url]); + } + const fetched = spawnSync(GIT, ["-C", target, "fetch", "--depth", "1", "origin", branch], { + stdio: "inherit", env: process.env, + }); + if (fetched.status !== 0) failWithBranches(branch, url); + const reset = spawnSync(GIT, ["-C", target, "reset", "--hard", "FETCH_HEAD"], { + stdio: "inherit", env: process.env, + }); + if (reset.status !== 0) failWithBranches(branch, url); + } else if (existsSync(target)) { + console.error(`❌ ${target} exists but is not a git repo.`); + process.exit(1); + } else { + console.log(`Cloning '${dest}' @ '${branch}'...`); + const cloned = spawnSync( + GIT, + ["clone", "--single-branch", "--branch", branch, "--depth", "1", url, target], + { stdio: "inherit", env: process.env }, + ); + if (cloned.status !== 0) failWithBranches(branch, url); + } +} + +// ============================================================================= +// Directory walking (used by lint, stale-artifact cleanup) +// ============================================================================= + +const PRUNE_DIRS = new Set([ + "node_modules", ".git", "build", "versioned_docs", "_partials", "_remotes", +]); + +function* walkMarkdown(dir) { + let entries; + try { + entries = readdirSync(dir, { withFileTypes: true }); + } catch { + return; + } + for (const e of entries) { + const p = join(dir, e.name); + if (e.isDirectory()) { + if (PRUNE_DIRS.has(e.name)) continue; + yield* walkMarkdown(p); + } else if (/\.(md|mdx)$/i.test(e.name) && !e.name.startsWith("_")) { + yield p; + } + } +} + +// ============================================================================= +// sync_versioned_remote +// ============================================================================= + +// Copy a remote's versioned-docs subtree up to the unified-doc site root. +// (Mirror of Invoke-SyncVersionedRemote in build-docs.ps1 -- keep in sync.) +function syncVersionedRemote(remote) { + let remoteDir = ""; + for (const sub of ["website", "docusaurus"]) { + const candidate = join(remotesDir, remote, sub); + if (existsSync(candidate)) { remoteDir = candidate; break; } + } + if (!remoteDir) { + console.error(`ERROR: cannot find _remotes/${remote}/{website,docusaurus}`); + process.exit(1); + } + + console.log(`Copying versioned docs from ${remoteDir}...`); + for (const item of [ + `${remote}_versioned_docs`, + `${remote}_versioned_sidebars`, + `${remote}_versions.json`, + ]) { + const src = join(remoteDir, item); + const dest = join(scriptDir, item); + if (!existsSync(src)) { + console.log(` WARN: source missing: ${src} -- skipping`); + continue; + } + rmSync(dest, { recursive: true, force: true }); + cpSync(src, dest, { recursive: true }); + console.log(` copied ${item}`); + } +} + +// ============================================================================= +// lint_docs +// ============================================================================= + +function stripAnsi(s) { + // eslint-disable-next-line no-control-regex + return s.replace(/\x1b\[[0-9;]*m/g, ""); +} + +function cleanLog(s) { + return (s || "") + .split(/\r?\n/) + .map((l) => stripAnsi(l).replace(/.*[\\/]_remotes[\\/]/, "_remotes/")) + .join("\n"); +} + +function lintDocs() { + console.log("πŸ” Starting Quality Checks..."); + + const potentialTargets = [ + join(remotesDir, "zlan", "docusaurus", "docs"), + join(remotesDir, "frontdoor", "docusaurus", "docs"), + join(remotesDir, "zrok", "website", "docs"), + join(remotesDir, "selfhosted", "docusaurus", "docs"), + join(remotesDir, "openziti", "docusaurus", "docs"), + join(remotesDir, "platform", "docusaurus", "docs"), + join(remotesDir, "data-connector", "docusaurus", "docs"), + join(remotesDir, "customer-connect", "docusaurus", "docs"), + ]; + const validTargets = potentialTargets.filter((t) => existsSync(t)); + + if (validTargets.length === 0) { + console.log("⚠️ No documentation directories found. Skipping lint."); + return; + } + + console.log("🎯 Gathering file list..."); + const files = []; + for (const t of validTargets) { + for (const f of walkMarkdown(t)) files.push(f); + } + console.log(`πŸ“Š Found ${files.length} files to scan...`); + if (files.length === 0) { + console.log("⚠️ No files found. Skipping."); + return; + } + + const valeIni = join(scriptDir, "..", "docs-linter", ".vale.ini"); + const mdlintJson = join(scriptDir, "..", "docs-linter", ".markdownlint.json"); + + let valeOut = ""; + if (has(VALE)) { + console.log("πŸ“ Running Vale..."); + for (const batch of chunk(files, LINT_BATCH)) { + const r = capture(VALE, ["--config", valeIni, "--no-wrap", "--no-exit", ...batch], { + timeout: 120000, + }); + valeOut += (r.stdout || "") + (r.stderr || ""); + } + } + + let mdOut = ""; + if (has(MDLINT)) { + console.log("🧹 Running Markdownlint..."); + for (const batch of chunk(files, LINT_BATCH)) { + const r = capture(MDLINT, ["--config", mdlintJson, ...batch], { timeout: 120000 }); + mdOut += (r.stdout || "") + (r.stderr || ""); + } + } + + const valeClean = cleanLog(valeOut); + const mdClean = cleanLog(mdOut); + + const countLines = (s, sub) => s.split("\n").filter((l) => l.includes(sub)).length; + const vErr = countLines(valeClean, "error"); + const vWarn = countLines(valeClean, "warning"); + const vSug = countLines(valeClean, "suggestion"); + const mdErr = mdClean.split("\n").filter((l) => l.trim() !== "").length; + const total = vErr + vWarn + vSug + mdErr; + + console.log(""); + console.log("========================================================"); + console.log("πŸ“Š QUALITY CHECK SUMMARY"); + console.log("========================================================"); + console.log(` πŸ“„ Files Scanned: ${files.length}`); + console.log(` πŸ›‘ Vale Errors: ${vErr}`); + console.log(` ⚠️ Vale Warnings: ${vWarn}`); + console.log(` πŸ’‘ Vale Suggestions: ${vSug}`); + console.log(` 🧹 Markdownlint Issues: ${mdErr}`); + console.log("--------------------------------------------------------"); + console.log(` 🚨 TOTAL ISSUES: ${total}`); + console.log("========================================================"); + console.log(""); + + if (mdErr > 0) { + console.log("################### MARKDOWNLINT REPORT ###################"); + console.log(mdClean.trim()); + console.log(""); + } + if (vErr + vWarn + vSug > 0) { + console.log("####################### VALE REPORT #######################"); + console.log(valeClean.trim()); + if (mdErr > 0) { + console.log(`πŸ›‘ BUT WAIT! You also have ${mdErr} Markdownlint errors (see above).`); + } + console.log(""); + } + + console.log("βœ… Quality Checks Complete."); +} + +// ============================================================================= +// MAIN EXECUTION +// ============================================================================= + +if (clean) { + console.log("CLEAN: removing _remotes contents (preserving package.json)"); + for (const name of readdirSync(remotesDir)) { + if (name === "package.json") continue; + rmSync(join(remotesDir, name), { recursive: true, force: true }); + } +} + +cloneOrUpdate("https://bitbucket.org/netfoundry/zrok-connector.git", "frontdoor", branches.frontdoor); +cloneOrUpdate("https://bitbucket.org/netfoundry/k8s-on-prem-installations.git", "selfhosted", branches.selfhosted); +cloneOrUpdate("https://github.com/openziti/ziti-doc.git", "openziti", branches.zitiDoc); +cloneOrUpdate("https://github.com/netfoundry/zlan.git", "zlan", branches.zlan); +cloneOrUpdate("https://github.com/openziti/zrok.git", "zrok", branches.zrok); +cloneOrUpdate("https://bitbucket.org/netfoundry/platform-doc.git", "platform", branches.platform); +cloneOrUpdate("https://bitbucket.org/netfoundry/nf-data-connector.git", "data-connector", branches.dataConnector); +cloneOrUpdate("https://bitbucket.org/netfoundry/customer-connect-docs.git", "customer-connect", branches.customerConnect); + +// Remove stale Docusaurus caches/outputs left inside cloned remotes. +console.log("Cleaning stale build artifacts from remotes..."); +for (const remote of (existsSync(remotesDir) ? readdirSync(remotesDir, { withFileTypes: true }) : [])) { + if (!remote.isDirectory()) continue; + for (const sub of ["docusaurus", "website"]) { + for (const artifact of ["build", ".docusaurus"]) { + const p = join(remotesDir, remote.name, sub, artifact); + if (existsSync(p)) rmSync(p, { recursive: true, force: true }); + } + } +} + +syncVersionedRemote("zrok"); +syncVersionedRemote("openziti"); + +lintDocs(); + +if (lintOnly) { + console.log("πŸ›‘ --lint-only specified. Exiting before build."); + process.exit(0); +} + +// --- BUILD OPENZITI SDK REFERENCE DOCS (ziti-doc's gendoc) --- +const sdkTarget = join(scriptDir, "static", "openziti", "reference", "developer", "sdk"); +console.log(`creating openziti SDK target if necessary at: ${sdkTarget}`); +mkdirSync(sdkTarget, { recursive: true }); + +const gendocEnv = { ...process.env, SDK_ROOT_TARGET: sdkTarget }; +const gendocFlags = ["-d", ...otherFlags]; // -d = skip gendoc's own docusaurus build +if (isWin) { + run("pwsh", ["-NoProfile", "-File", join(remotesDir, "openziti", "gendoc.ps1"), ...gendocFlags], { + env: gendocEnv, cwd: scriptDir, + }); +} else { + // Execute gendoc.sh directly so its `#!/bin/bash -eu` shebang applies (as the + // former build-docs.sh did); running it via `bash gendoc.sh` would drop -eu. + run(join(remotesDir, "openziti", "gendoc.sh"), gendocFlags, { + env: gendocEnv, cwd: scriptDir, + }); +} + +// --- DOCUSAURUS BUILD --- +run(YARN, ["install"], { cwd: scriptDir }); + +if (clean) { + console.log("CLEAN: clearing Docusaurus cache"); + run(YARN, ["clear"], { cwd: scriptDir }); +} + +const now = new Date().toString(); +const commitRes = capture(GIT, ["-C", scriptDir, "rev-parse", "--short", "HEAD"]); +const commit = commitRes.status === 0 && commitRes.stdout.trim() ? commitRes.stdout.trim() : "unknown"; +writeFileSync(join(scriptDir, "static", "build-time.txt"), `${now}\n${commit}\n`); + +const minifyFlag = process.env.NO_MINIFY ? ["--no-minify"] : []; +const outDir = `build${qualifier}`; + +console.log(line); +console.log("DOCUSAURUS BUILD"); +console.log(line); +console.log(` Output dir: ${outDir}`); +console.log(` Build mask: ${process.env.DOCUSAURUS_BUILD_MASK ?? "0x3FF (config default)"}`); +console.log(` No-minify: ${process.env.NO_MINIFY ? "true" : "false"}`); +console.log(line); + +run(YARN, ["build", ...minifyFlag, "--out-dir", outDir], { cwd: scriptDir }); diff --git a/unified-doc/build-docs.ps1 b/unified-doc/build-docs.ps1 index 149c9f1..a01bd24 100644 --- a/unified-doc/build-docs.ps1 +++ b/unified-doc/build-docs.ps1 @@ -1,17 +1,15 @@ #Requires -Version 5.1 <# .SYNOPSIS - Builds the unified NetFoundry documentation site. + Thin Windows shim for the unified NetFoundry documentation build. .DESCRIPTION - Clones (or updates) all product doc repos into _remotes/, runs lint checks, - builds SDK reference docs via ziti-doc's gendoc.sh, then runs a Docusaurus - production build. + All build logic lives in build-docs.mjs, the single cross-platform source of + truth (shared with build-docs.sh). This script only maps its PowerShell-style + parameters onto build-docs.mjs flags/env vars so existing Windows callers + (e.g. visual-diff.ps1 -SkipLinkedDoc) keep working unchanged. - Auth: token env vars are used when set; otherwise falls back to SSH key auth. - Token env vars: GH_ZITI_CI_REPO_ACCESS_PAT, BB_REPO_TOKEN_ONPREM, - BB_REPO_TOKEN_FRONTDOOR, BB_REPO_TOKEN_PLATFORM_DOC, - BB_REPO_TOKEN_DATA_CONNECTOR, BB_USERNAME. + Run `node build-docs.mjs --help` for the full option/env-var reference. .EXAMPLE .\build-docs.ps1 -ZitiDocBranch my.branch.name @@ -24,14 +22,15 @@ #> [CmdletBinding()] param( - # Branch to clone for each remote repo - [string]$ZitiDocBranch = "main", - [string]$ZrokBranch = "main", - [string]$FrontdoorBranch = "develop", - [string]$SelfhostedBranch = "main", - [string]$ZlanBranch = "main", - [string]$PlatformBranch = "main", + # Branch to clone for each remote repo (only forwarded when explicitly set) + [string]$ZitiDocBranch = "main", + [string]$ZrokBranch = "main", + [string]$FrontdoorBranch = "develop", + [string]$SelfhostedBranch = "main", + [string]$ZlanBranch = "main", + [string]$PlatformBranch = "main", [string]$DataConnectorBranch = "main", + [string]$CustomerConnectBranch = "main", # Remove all _remotes content and .docusaurus cache before building [switch]$Clean, @@ -39,7 +38,7 @@ param( # Run lint checks only; skip the Docusaurus build [switch]$LintOnly, - # Pass -l to gendoc.sh: skip doxygen/wget SDK reference doc generation + # Skip doxygen/wget SDK reference doc generation (forwards -l to gendoc) [switch]$SkipLinkedDoc, # Pass --no-minify to Docusaurus build @@ -49,342 +48,38 @@ param( [string]$Qualifier = "", # Docusaurus build mask (hex). 0x1=openziti, 0x2=frontdoor, 0x4=selfhosted, - # 0x8=zrok, 0x10=zlan, 0x20=platform, 0x40=data-connector, 0xFF=all - [string]$BuildMask = "0xFF" + # 0x8=zrok, 0x10=zlan, 0x20=platform, 0x40=data-connector, + # 0x80=llm-gateway, 0x100=mcp-gateway, 0x200=customer-connect, 0x3FF=all. + # Only forwarded (as $env:DOCUSAURUS_BUILD_MASK) when explicitly set; + # otherwise build-docs.mjs lets docusaurus.config.ts default it (0x3FF). + [string]$BuildMask = "0x3FF" ) Set-StrictMode -Version Latest $ErrorActionPreference = "Stop" -$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path -$remotesDir = Join-Path $scriptDir "_remotes" - -# ─── HELPERS ────────────────────────────────────────────────────────────────── - -function Write-Separator([string]$Title = "") { - Write-Host "========================================" - if ($Title) { Write-Host $Title; Write-Host "========================================" } -} - -# Builds an authenticated clone URL. Falls back to $SshUrl when the token var is unset. -function Get-RepoUrl { - param( - [string]$DefaultHttpsUrl, - [string]$TokenEnvVar, - [string]$SshUrl, - # For Bitbucket: username env var (defaults to "x-token-auth") - [string]$UsernameEnvVar = "" - ) - - $token = [System.Environment]::GetEnvironmentVariable($TokenEnvVar) - if ($token) { - $user = "x-access-token" - if ($UsernameEnvVar) { - $u = [System.Environment]::GetEnvironmentVariable($UsernameEnvVar) - if ($u) { $user = $u } else { $user = "x-token-auth" } - } - $uri = [Uri]$DefaultHttpsUrl - return "$($uri.Scheme)://${user}:${token}@$($uri.Host)$($uri.AbsolutePath)" - } - return $SshUrl -} - -# Clones $Url into _remotes\$Dest at $Branch (depth 1). -# If the clone fails and an existing repo is present, does fetch + reset instead. -# On any unrecoverable error, lists available remote branches and exits. -function Invoke-CloneOrUpdate { - param( - [string]$Url, - [string]$Dest, - [string]$Branch - ) - - $target = Join-Path $remotesDir $Dest - $redactedUrl = $Url -replace '://[^@]+@', '://[REDACTED]@' - - if (Test-Path (Join-Path $target ".git")) { - Write-Host "Updating '$Dest' @ '$Branch'..." - git -C $target remote set-url origin $Url 2>&1 | Out-Null - if ($LASTEXITCODE -ne 0) { - git -C $target remote add origin $Url 2>&1 | Out-Null - } - git -C $target fetch --depth 1 origin $Branch - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: Branch '$Branch' not found in $redactedUrl" - Write-Host "Available branches:" - git ls-remote --heads $Url | ForEach-Object { - ($_ -split '\s+')[1] -replace 'refs/heads/', '' - } - exit 1 - } - git -C $target reset --hard FETCH_HEAD 2>&1 - if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to reset '$target' to FETCH_HEAD" - } - return - } elseif (Test-Path $target) { - Write-Host "ERROR: $target exists but is not a git repo" - Get-ChildItem $target | Format-List Name - exit 1 - } else { - Write-Host "Cloning '$Dest' @ '$Branch'..." - git clone --single-branch --branch $Branch --depth 1 $Url $target - if ($LASTEXITCODE -ne 0) { - Write-Host "ERROR: Clone failed. Available branches in $redactedUrl :" - git ls-remote --heads $Url | ForEach-Object { - ($_ -split '\s+')[1] -replace 'refs/heads/', '' - } - exit 1 - } - } -} - -# Exposes a remote's versioned-docs at the unified-doc site root. -# (Mirror of sync-versioned-remote.sh -- keep both in sync.) -# -# Docusaurus's plugin-content-docs hardcodes its lookup to siteDir/_versioned_docs/, -# so the snapshots have to live at the root. Uses straight copies; symlinks/ -# junctions/hardlinks all caused Docusaurus to resolve files to their -# underlying _remotes/ path, which broke per-plugin remark pipelines (they -# path-match against the plugin's declared `path`). -# -# Each remote's versioned-docs subtree (_versioned_docs/, -# _versioned_sidebars/, _versions.json) lives inside the cloned -# remote, but the subdir name varies (zrok uses 'website', openziti uses -# 'docusaurus'); this auto-detects. -function Invoke-SyncVersionedRemote([string]$Remote) { - $remoteDir = $null - foreach ($sub in @("website", "docusaurus")) { - $candidate = Join-Path $remotesDir "$Remote\$sub" - if (Test-Path $candidate) { $remoteDir = $candidate; break } - } - if (-not $remoteDir) { - Write-Error "Cannot find _remotes\$Remote\{website,docusaurus}" - return - } - Write-Host "Copying versioned docs from $remoteDir..." - - $items = @("${Remote}_versioned_docs", "${Remote}_versioned_sidebars", "${Remote}_versions.json") - foreach ($item in $items) { - $dest = Join-Path $scriptDir $item - $src = Join-Path $remoteDir $item - if (-not (Test-Path $src)) { - Write-Host " WARN: source missing: $src -- skipping" - continue - } - Remove-Item -Recurse -Force $dest -ErrorAction SilentlyContinue - Copy-Item -Recurse $src $dest - Write-Host " copied $item" - } -} - -function Invoke-LintDocs { - Write-Host "Starting quality checks..." - - $potentialTargets = @( - (Join-Path $remotesDir "zlan\docusaurus\docs"), - (Join-Path $remotesDir "frontdoor\docusaurus\docs"), - (Join-Path $remotesDir "zrok\website\docs"), - (Join-Path $remotesDir "selfhosted\docusaurus\docs"), - (Join-Path $remotesDir "openziti\docusaurus\docs"), - (Join-Path $remotesDir "platform\docusaurus\docs"), - (Join-Path $remotesDir "data-connector\docusaurus\docs") - ) - $targets = $potentialTargets | Where-Object { Test-Path $_ } - - if (-not $targets) { - Write-Host "No documentation directories found. Skipping lint." - return - } - - $valeIni = Join-Path $scriptDir "..\docs-linter\.vale.ini" - $mdlintJson = Join-Path $scriptDir "..\docs-linter\.markdownlint.json" - - $valeOk = $null -ne (Get-Command vale -ErrorAction SilentlyContinue) - $mdlintOk = $null -ne (Get-Command markdownlint -ErrorAction SilentlyContinue) - - $valeErrors = 0; $valeWarnings = 0; $valeSugg = 0; $mdErrors = 0 - - if ($valeOk) { - Write-Host "Running Vale..." - $valeOut = & vale --config $valeIni --no-wrap --no-exit @targets 2>&1 - $valeErrors = ($valeOut | Select-String "\berror\b" | Measure-Object).Count - $valeWarnings = ($valeOut | Select-String "\bwarning\b" | Measure-Object).Count - $valeSugg = ($valeOut | Select-String "\bsuggestion\b" | Measure-Object).Count - if ($valeErrors + $valeWarnings + $valeSugg -gt 0) { - $valeOut | Write-Host - } - } - - if ($mdlintOk) { - Write-Host "Running markdownlint..." - $mdOut = & markdownlint --config $mdlintJson @targets 2>&1 - $mdErrors = ($mdOut | Measure-Object).Count - if ($mdErrors -gt 0) { $mdOut | Write-Host } - } - - $total = $valeErrors + $valeWarnings + $valeSugg + $mdErrors - Write-Host "" - Write-Host "========================================================" - Write-Host " QUALITY CHECK SUMMARY" - Write-Host "========================================================" - Write-Host " Files: (by directory)" - $targets | ForEach-Object { Write-Host " $_" } - Write-Host " Vale Errors: $valeErrors" - Write-Host " Vale Warnings: $valeWarnings" - Write-Host " Vale Suggestions: $valeSugg" - Write-Host " Markdownlint Issues: $mdErrors" - Write-Host " TOTAL ISSUES: $total" - Write-Host "========================================================" -} - -# ─── MAIN ───────────────────────────────────────────────────────────────────── - -Write-Separator "BUILD CONFIGURATION" -Write-Host " ZitiDocBranch: $ZitiDocBranch" -Write-Host " ZrokBranch: $ZrokBranch" -Write-Host " FrontdoorBranch: $FrontdoorBranch" -Write-Host " SelfhostedBranch: $SelfhostedBranch" -Write-Host " ZlanBranch: $ZlanBranch" -Write-Host " PlatformBranch: $PlatformBranch" -Write-Host " DataConnectorBranch: $DataConnectorBranch" -Write-Host " Clean: $Clean" -Write-Host " LintOnly: $LintOnly" -Write-Host " SkipLinkedDoc: $SkipLinkedDoc" -Write-Host " NoMinify: $NoMinify" -Write-Host " Qualifier: '$Qualifier'" -Write-Host " BuildMask: $BuildMask" -Write-Host " IS_VERCEL: $($env:IS_VERCEL)" -Write-Host " node: $(node --version 2>$null)" -Write-Host " yarn: $(yarn --version 2>$null)" - -if ($Clean) { - Write-Host "CLEAN: removing _remotes contents (preserving package.json)" - Get-ChildItem $remotesDir -Exclude "package.json" | - Remove-Item -Recurse -Force -ErrorAction SilentlyContinue -} - -# ─── RESOLVE AUTHENTICATED URLS ─────────────────────────────────────────────── - -$urlZitiDoc = Get-RepoUrl ` - -DefaultHttpsUrl "https://github.com/openziti/ziti-doc.git" ` - -TokenEnvVar "GH_ZITI_CI_REPO_ACCESS_PAT" ` - -SshUrl "git@github.com:openziti/ziti-doc.git" - -$urlZlan = Get-RepoUrl ` - -DefaultHttpsUrl "https://github.com/netfoundry/zlan.git" ` - -TokenEnvVar "GH_ZITI_CI_REPO_ACCESS_PAT" ` - -SshUrl "git@github.com:netfoundry/zlan.git" - -$urlFrontdoor = Get-RepoUrl ` - -DefaultHttpsUrl "https://bitbucket.org/netfoundry/zrok-connector.git" ` - -TokenEnvVar "BB_REPO_TOKEN_FRONTDOOR" ` - -SshUrl "git@bitbucket.org:netfoundry/zrok-connector.git" ` - -UsernameEnvVar "BB_USERNAME" - -$urlSelfhosted = Get-RepoUrl ` - -DefaultHttpsUrl "https://bitbucket.org/netfoundry/k8s-on-prem-installations.git" ` - -TokenEnvVar "BB_REPO_TOKEN_ONPREM" ` - -SshUrl "git@bitbucket.org:netfoundry/k8s-on-prem-installations.git" ` - -UsernameEnvVar "BB_USERNAME" - -$urlZrok = "https://github.com/openziti/zrok.git" # public; no auth needed - -$urlPlatform = Get-RepoUrl ` - -DefaultHttpsUrl "https://bitbucket.org/netfoundry/platform-doc.git" ` - -TokenEnvVar "BB_REPO_TOKEN_PLATFORM_DOC" ` - -SshUrl "git@bitbucket.org:netfoundry/platform-doc.git" ` - -UsernameEnvVar "BB_USERNAME" - -$urlDataConnector = Get-RepoUrl ` - -DefaultHttpsUrl "https://bitbucket.org/netfoundry/nf-data-connector.git" ` - -TokenEnvVar "BB_REPO_TOKEN_DATA_CONNECTOR" ` - -SshUrl "git@bitbucket.org:netfoundry/nf-data-connector.git" ` - -UsernameEnvVar "BB_USERNAME" - -# ─── CLONE / UPDATE REMOTES ─────────────────────────────────────────────────── - -Invoke-CloneOrUpdate $urlFrontdoor "frontdoor" $FrontdoorBranch -Invoke-CloneOrUpdate $urlSelfhosted "selfhosted" $SelfhostedBranch -Invoke-CloneOrUpdate $urlZitiDoc "openziti" $ZitiDocBranch -Invoke-CloneOrUpdate $urlZlan "zlan" $ZlanBranch -Invoke-CloneOrUpdate $urlZrok "zrok" $ZrokBranch -Invoke-CloneOrUpdate $urlPlatform "platform" $PlatformBranch -Invoke-CloneOrUpdate $urlDataConnector "data-connector" $DataConnectorBranch - -# Remove stale Docusaurus caches and build outputs from inside the cloned remotes. -# A leftover .docusaurus/ or build/ from a prior run can confuse the unified-doc build. -Get-ChildItem $remotesDir -Recurse -Directory -ErrorAction SilentlyContinue | - Where-Object { $_.Name -in 'build', '.docusaurus' } | - Where-Object { $_.FullName -match '(\\docusaurus|\\website)(\\build|\\\.docusaurus)$' } | - ForEach-Object { - Write-Host "Removing stale artifact: $($_.FullName)" - Remove-Item $_.FullName -Recurse -Force - } - -# ─── SYNC VERSIONED DOCS ────────────────────────────────────────────────────── - -Invoke-SyncVersionedRemote "zrok" -Invoke-SyncVersionedRemote "openziti" - -# ─── LINT ───────────────────────────────────────────────────────────────────── - -Invoke-LintDocs - -if ($LintOnly) { - Write-Host "-LintOnly specified. Exiting before build." - exit 0 -} - -# ─── SDK REFERENCE DOCS (ziti-doc's gendoc.sh) ──────────────────────────────── -# gendoc.sh is always called with -d (skip its own Docusaurus build; unified-doc -# handles that). Pass -l as well when -SkipLinkedDoc is set (skips doxygen/wget). - -$sdkTarget = Join-Path $scriptDir "static\openziti\reference\developer\sdk" -New-Item -ItemType Directory -Force -Path $sdkTarget | Out-Null -$env:SDK_ROOT_TARGET = $sdkTarget - -$gendocScript = Join-Path $remotesDir "openziti\gendoc.ps1" -$gendocFlags = @("-d") -if ($SkipLinkedDoc) { $gendocFlags += "-l" } - -Write-Host "Running gendoc.ps1 $($gendocFlags -join ' ')..." -& pwsh -NoProfile -File $gendocScript @gendocFlags -if ($LASTEXITCODE -ne 0) { - Write-Error "gendoc.ps1 failed with exit code $LASTEXITCODE" -} - -# ─── DOCUSAURUS BUILD ───────────────────────────────────────────────────────── - -Push-Location $scriptDir -try { - & yarn install - if ($LASTEXITCODE -ne 0) { Write-Error "yarn install failed" } - - if ($Clean) { - Write-Host "CLEAN: clearing Docusaurus cache" - & yarn clear - } - - # Stamp build time and commit into static/ for diagnostics - $now = Get-Date -Format "ddd MMM dd HH:mm:ss UTC yyyy" -AsUTC - $commit = git -C $scriptDir rev-parse --short HEAD 2>$null - if (-not $commit) { $commit = "unknown" } - "$now`n$commit" | Set-Content (Join-Path $scriptDir "static\build-time.txt") - - $env:DOCUSAURUS_BUILD_MASK = $BuildMask - - $outDir = "build$Qualifier" - $buildArgs = @("build", "--out-dir", $outDir) - if ($NoMinify) { $buildArgs += "--no-minify" } - - Write-Separator "DOCUSAURUS BUILD" - Write-Host " Output dir: $outDir" - Write-Host " Build mask: $BuildMask" - Write-Host " No-minify: $NoMinify" - - & yarn @buildArgs - if ($LASTEXITCODE -ne 0) { Write-Error "yarn build failed" } -} finally { - Pop-Location -} +$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$mjs = Join-Path $scriptDir "build-docs.mjs" + +# Map PowerShell params -> build-docs.mjs flags. Only forward params the caller +# explicitly passed so build-docs.mjs owns the defaults (single source of truth). +$mjsArgs = @() +if ($PSBoundParameters.ContainsKey('ZitiDocBranch')) { $mjsArgs += "--ziti-doc-branch=$ZitiDocBranch" } +if ($PSBoundParameters.ContainsKey('ZrokBranch')) { $mjsArgs += "--zrok-branch=$ZrokBranch" } +if ($PSBoundParameters.ContainsKey('FrontdoorBranch')) { $mjsArgs += "--frontdoor-branch=$FrontdoorBranch" } +if ($PSBoundParameters.ContainsKey('SelfhostedBranch')) { $mjsArgs += "--selfhosted-branch=$SelfhostedBranch" } +if ($PSBoundParameters.ContainsKey('ZlanBranch')) { $mjsArgs += "--zlan-branch=$ZlanBranch" } +if ($PSBoundParameters.ContainsKey('PlatformBranch')) { $mjsArgs += "--platform-branch=$PlatformBranch" } +if ($PSBoundParameters.ContainsKey('DataConnectorBranch')) { $mjsArgs += "--data-connector-branch=$DataConnectorBranch" } +if ($PSBoundParameters.ContainsKey('CustomerConnectBranch')){ $mjsArgs += "--customer-connect-branch=$CustomerConnectBranch" } +if ($Clean) { $mjsArgs += "--clean" } +if ($LintOnly) { $mjsArgs += "--lint-only" } +if ($SkipLinkedDoc) { $mjsArgs += "-l" } +if ($Qualifier) { $mjsArgs += "--qualifier=$Qualifier" } + +# Env-var controls, matching build-docs.sh semantics. +if ($NoMinify) { $env:NO_MINIFY = "1" } +if ($PSBoundParameters.ContainsKey('BuildMask')) { $env:DOCUSAURUS_BUILD_MASK = $BuildMask } + +& node $mjs @mjsArgs +exit $LASTEXITCODE diff --git a/unified-doc/build-docs.sh b/unified-doc/build-docs.sh index b9b9a3a..24ae136 100755 --- a/unified-doc/build-docs.sh +++ b/unified-doc/build-docs.sh @@ -1,466 +1,13 @@ #!/usr/bin/env bash # ============================================================================= -# build-docs.sh β€” Build the unified NetFoundry documentation site. +# build-docs.sh β€” thin platform shim. # -# Clones (or updates) all product doc repos into _remotes/, runs lint checks, -# builds SDK reference docs via ziti-doc's gendoc.sh, then runs a Docusaurus -# production build. +# All build logic lives in build-docs.mjs, the single cross-platform source of +# truth (shared with build-docs.ps1). This script only forwards its arguments so +# existing callers (CI, publish-unified-doc.sh, visual-diff.sh) keep working. # -# USAGE -# build-docs.sh [OPTIONS] -# -# OPTIONS -# --ziti-doc-branch=BRANCH Branch for openziti/ziti-doc (default: main) -# --zrok-branch=BRANCH Branch for openziti/zrok (default: main) -# --frontdoor-branch=BRANCH Branch for netfoundry/zrok-connector (default: develop) -# --selfhosted-branch=BRANCH Branch for netfoundry/k8s-on-prem-installations (default: main) -# --zlan-branch=BRANCH Branch for netfoundry/zlan (default: main) -# --platform-branch=BRANCH Branch for netfoundry/platform-doc (default: main) -# --data-connector-branch=BRANCH Branch for netfoundry/nf-data-connector (default: main) -# --customer-connect-branch=BRANCH Branch for netfoundry/customer-connect-docs (default: main) -# --clean Wipe _remotes and .docusaurus cache before building -# --lint-only Run lint checks only; skip build -# --qualifier=VALUE Append VALUE to output dir (e.g. --qualifier=-preview -> build-preview) -# -l (gendoc) Skip linked doc generation (doxygen/wget) -# -g (gendoc) Skip git clones inside gendoc -# -c (gendoc) Skip clean steps inside gendoc -# -h, --help Show this help and exit -# -# ENVIRONMENT VARIABLES -# GH_ZITI_CI_REPO_ACCESS_PAT GitHub PAT for ziti-doc and zlan (falls back to SSH) -# BB_REPO_TOKEN_FRONTDOOR Bitbucket token for zrok-connector (falls back to SSH) -# BB_REPO_TOKEN_ONPREM Bitbucket token for k8s-on-prem-installations (falls back to SSH) -# BB_REPO_TOKEN_PLATFORM_DOC Bitbucket token for platform-doc (falls back to SSH) -# BB_REPO_TOKEN_DATA_CONNECTOR Bitbucket token for nf-data-connector (falls back to SSH) -# BB_REPO_TOKEN_CUSTOMER_CONNECT Bitbucket token for customer-connect-docs (falls back to SSH) -# BB_USERNAME Bitbucket username (default: x-token-auth) -# DOCUSAURUS_BUILD_MASK Hex bitmask: 0x1=openziti 0x2=frontdoor 0x4=selfhosted -# 0x8=zrok 0x10=zlan 0x20=platform -# 0x40=data-connector 0x80=llm-gateway 0x100=mcp-gateway -# 0x200=customer-connect 0x3FF=all (default: 0x3FF) -# DOCUSAURUS_PUBLISH_ENV Set to 'prod' to use production Algolia index -# NO_MINIFY Set to any value to pass --no-minify to Docusaurus -# IS_VERCEL Set to 'true' on Vercel preview deployments -# -# EXAMPLES -# ./build-docs.sh --ziti-doc-branch=my.branch.name -# DOCUSAURUS_BUILD_MASK=0x1 ./build-docs.sh --ziti-doc-branch=my.branch.name -# ./build-docs.sh --clean --lint-only -# ./build-docs.sh --qualifier=-preview -l +# Run `node build-docs.mjs --help` for the full option/env-var reference. # ============================================================================= set -euo pipefail - -# --- ARGUMENT PARSING --- -CLEAN=0 -LINT_ONLY=0 -BUILD_QUALIFIER="" -QUALIFIER_FLAG=() -OTHER_FLAGS=() -EXTRA_ARGS=() - -BRANCH_ZITI_DOC="main" -BRANCH_ZROK="main" -BRANCH_FRONTDOOR="develop" -BRANCH_SELFHOSTED="main" -BRANCH_ZLAN="main" -BRANCH_PLATFORM="main" -BRANCH_DATA_CONNECTOR="main" -BRANCH_CUSTOMER_CONNECT="add-docs" - -usage() { - sed -n '/^# USAGE/,/^# =====/{ /^# =====/d; s/^# \{0,1\}//; p }' "$0" -} - -while [[ $# -gt 0 ]]; do - case $1 in - --ziti-doc-branch=*) BRANCH_ZITI_DOC="${1#*=}"; shift ;; - --zrok-branch=*) BRANCH_ZROK="${1#*=}"; shift ;; - --frontdoor-branch=*) BRANCH_FRONTDOOR="${1#*=}"; shift ;; - --selfhosted-branch=*) BRANCH_SELFHOSTED="${1#*=}"; shift ;; - --zlan-branch=*) BRANCH_ZLAN="${1#*=}"; shift ;; - --platform-branch=*) BRANCH_PLATFORM="${1#*=}"; shift ;; - --data-connector-branch=*) BRANCH_DATA_CONNECTOR="${1#*=}"; shift ;; - --customer-connect-branch=*) BRANCH_CUSTOMER_CONNECT="${1#*=}"; shift ;; - --ziti-doc-branch) BRANCH_ZITI_DOC="${2:?--ziti-doc-branch requires a value}"; shift 2 ;; - --zrok-branch) BRANCH_ZROK="${2:?--zrok-branch requires a value}"; shift 2 ;; - --frontdoor-branch) BRANCH_FRONTDOOR="${2:?--frontdoor-branch requires a value}"; shift 2 ;; - --selfhosted-branch) BRANCH_SELFHOSTED="${2:?--selfhosted-branch requires a value}"; shift 2 ;; - --zlan-branch) BRANCH_ZLAN="${2:?--zlan-branch requires a value}"; shift 2 ;; - --platform-branch) BRANCH_PLATFORM="${2:?--platform-branch requires a value}"; shift 2 ;; - --data-connector-branch) BRANCH_DATA_CONNECTOR="${2:?--data-connector-branch requires a value}"; shift 2 ;; - --customer-connect-branch) BRANCH_CUSTOMER_CONNECT="${2:?--customer-connect-branch requires a value}"; shift 2 ;; - --clean) CLEAN=1; shift ;; - --lint-only) LINT_ONLY=1; shift ;; - -h|--help) usage; exit 0 ;; - --qualifier=*) BUILD_QUALIFIER="${1#*=}"; QUALIFIER_FLAG=("$1"); shift ;; - --qualifier) - if [[ -n "${2:-}" && ! "$2" =~ ^- ]]; then - BUILD_QUALIFIER="$2"; QUALIFIER_FLAG=("--qualifier=$2"); shift 2 - else - echo "Error: --qualifier requires a value" >&2; exit 1 - fi - ;; - -*) OTHER_FLAGS+=("$1"); shift ;; - *) EXTRA_ARGS+=("$1"); shift ;; - esac -done - -echo "========================================" -echo "BUILD CONFIGURATION" -echo "========================================" -echo " BRANCH_ZITI_DOC='$BRANCH_ZITI_DOC'" -echo " BRANCH_ZROK='$BRANCH_ZROK'" -echo " BRANCH_FRONTDOOR='$BRANCH_FRONTDOOR'" -echo " BRANCH_SELFHOSTED='$BRANCH_SELFHOSTED'" -echo " BRANCH_ZLAN='$BRANCH_ZLAN'" -echo " BRANCH_PLATFORM='$BRANCH_PLATFORM'" -echo " BRANCH_DATA_CONNECTOR='$BRANCH_DATA_CONNECTOR'" -echo " BRANCH_CUSTOMER_CONNECT='$BRANCH_CUSTOMER_CONNECT'" -echo " CLEAN=$CLEAN" -echo " IS_VERCEL='${IS_VERCEL:-}'" -echo " node: $(node --version 2>/dev/null || echo 'not found')" -echo " yarn: $(yarn --version 2>/dev/null || echo 'not found')" -echo "========================================" - script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" - -# ============================================================================= -# HELPER FUNCTIONS -# ============================================================================= - -clone_or_update() { - local url="$1" dest="$2" branch="${3:-main}" - local target="$script_dir/_remotes/$dest" - - - # --- AUTHENTICATION LOGIC --- - case "$url" in - *zlan*) - if [ -n "${GH_ZITI_CI_REPO_ACCESS_PAT:-}" ]; then - url="https://x-access-token:${GH_ZITI_CI_REPO_ACCESS_PAT}@github.com/netfoundry/zlan.git" - echo "πŸ”‘ Using GH_ZITI_CI_REPO_ACCESS_PAT token for zlan" >&2 - else - url="git@github.com:netfoundry/zlan.git" - echo "πŸ”‘ Using SSH for zlan" >&2 - fi - ;; - *k8s-on-prem-installations*) - if [ -n "${BB_REPO_TOKEN_ONPREM:-}" ]; then - local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_ONPREM}@bitbucket.org/netfoundry/k8s-on-prem-installations.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_ONPREM token" >&2 - else - url="git@bitbucket.org:netfoundry/k8s-on-prem-installations.git" - echo "πŸ”‘ Using SSH for self-hosted" >&2 - fi - ;; - *zrok-connector*) - if [ -n "${BB_REPO_TOKEN_FRONTDOOR:-}" ]; then - local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_FRONTDOOR}@bitbucket.org/netfoundry/zrok-connector.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_FRONTDOOR token" >&2 - else - url="git@bitbucket.org:netfoundry/zrok-connector.git" - echo "πŸ”‘ Using SSH for frontdoor" >&2 - fi - ;; - *ziti-doc*) - if [ -n "${GH_ZITI_CI_REPO_ACCESS_PAT:-}" ]; then - url="https://x-access-token:${GH_ZITI_CI_REPO_ACCESS_PAT}@github.com/openziti/ziti-doc.git" - echo "πŸ”‘ Using GH_ZITI_CI_REPO_ACCESS_PAT token for ziti-doc" >&2 - else - url="git@github.com:openziti/ziti-doc.git" - echo "πŸ”‘ Using SSH for ziti-doc" >&2 - fi - ;; - *platform-doc*) - if [ -n "${BB_REPO_TOKEN_PLATFORM_DOC:-}" ]; then - local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_PLATFORM_DOC}@bitbucket.org/netfoundry/platform-doc.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_PLATFORM_DOC token" >&2 - else - url="git@bitbucket.org:netfoundry/platform-doc.git" - echo "πŸ”‘ Using SSH for platform-doc" >&2 - fi - ;; - *nf-data-connector*) - if [ -n "${BB_REPO_TOKEN_DATA_CONNECTOR:-}" ]; then - local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_DATA_CONNECTOR}@bitbucket.org/netfoundry/nf-data-connector.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_DATA_CONNECTOR token" >&2 - else - url="git@bitbucket.org:netfoundry/nf-data-connector.git" - echo "πŸ”‘ Using SSH for nf-data-connector" >&2 - fi - ;; - *customer-connect-docs*) - if [ -n "${BB_REPO_TOKEN_CUSTOMER_CONNECT:-}" ]; then - local bb_user="${BB_USERNAME:-x-token-auth}" - url="https://${bb_user}:${BB_REPO_TOKEN_CUSTOMER_CONNECT}@bitbucket.org/netfoundry/customer-connect-docs.git" - echo "πŸ”‘ Using BB_REPO_TOKEN_CUSTOMER_CONNECT token" >&2 - else - url="git@bitbucket.org:netfoundry/customer-connect-docs.git" - echo "πŸ”‘ Using SSH for customer-connect-docs" >&2 - fi - ;; - esac - - if [ -d "$target/.git" ]; then - echo "Updating '$dest' @ '$branch'..." - git -C "$target" remote set-url origin "$url" 2>&1 || git -C "$target" remote add origin "$url" 2>&1 || true - if ! git -C "$target" fetch --depth 1 origin "$branch" 2>&1 \ - || ! git -C "$target" reset --hard FETCH_HEAD 2>&1; then - echo "❌ Branch '$branch' not found in ${url//:*@/://[REDACTED]@}" - echo "πŸ‘‰ Available branches:" - git ls-remote --heads "$url" | awk '{print $2}' | sed 's|refs/heads/||' - exit 1 - fi - elif [ -d "$target" ]; then - echo "❌ ${target} exists but is not a git repo." - ls -la "$target" 2>&1 || true - exit 1 - else - echo "Cloning '$dest' @ '$branch'..." - if ! git clone --single-branch --branch "$branch" --depth 1 "$url" "$target" 2>&1; then - echo "❌ Clone failed. Available branches in ${url//:*@/://[REDACTED]@}:" - git ls-remote --heads "$url" | awk '{print $2}' | sed 's|refs/heads/||' - exit 1 - fi - fi -} - -# Exposes a remote's versioned-docs at the unified-doc site root via straight -# copies (Docusaurus's plugin-content-docs hardcodes its lookup to -# siteDir/_versioned_docs/, so the snapshots have to live at the root). -# Symlinks/junctions/hardlinks all caused Docusaurus to resolve files to their -# underlying _remotes/ path, which broke per-plugin remark pipelines. -# -# Each remote's versioned-docs subtree lives inside the cloned remote, but the -# subdir varies (zrok uses 'website', openziti uses 'docusaurus'); auto-detect. -# (Mirror of Invoke-SyncVersionedRemote in build-docs.ps1 -- keep in sync.) -sync_versioned_remote() { - local remote="$1" - local remote_dir="" - for sub in website docusaurus; do - if [ -d "$script_dir/_remotes/$remote/$sub" ]; then - remote_dir="$script_dir/_remotes/$remote/$sub" - break - fi - done - - if [ -z "$remote_dir" ]; then - echo "ERROR: cannot find _remotes/$remote/{website,docusaurus}" - exit 1 - fi - - echo "Copying versioned docs from $remote_dir..." - - for item in "${remote}_versioned_docs" "${remote}_versioned_sidebars" "${remote}_versions.json"; do - local dest="$script_dir/$item" - local src="$remote_dir/$item" - if [ ! -e "$src" ]; then - echo " WARN: source missing: $src -- skipping" - continue - fi - rm -rf "$dest" - cp -r "$src" "$dest" - echo " copied $item" - done -} - -lint_docs() { - echo "πŸ” Starting Quality Checks..." - - # 1. DEFINE TARGETS - POTENTIAL_TARGETS=( - "${script_dir}/_remotes/zlan/docusaurus/docs" - "${script_dir}/_remotes/frontdoor/docusaurus/docs" - "${script_dir}/_remotes/zrok/website/docs" - "${script_dir}/_remotes/selfhosted/docusaurus/docs" - "${script_dir}/_remotes/openziti/docusaurus/docs" - "${script_dir}/_remotes/platform/docusaurus/docs" - "${script_dir}/_remotes/data-connector/docusaurus/docs" - "${script_dir}/_remotes/customer-connect/docusaurus/docs" - ) - - # 2. VERIFY FOLDERS - VALID_TARGETS=() - for target in "${POTENTIAL_TARGETS[@]}"; do - if [ -d "$target" ]; then - VALID_TARGETS+=("$target") - fi - done - - if [ ${#VALID_TARGETS[@]} -eq 0 ]; then - echo "⚠️ No documentation directories found. Skipping lint." - return - fi - - # 3. GENERATE CLEAN FILE LIST - echo "🎯 Gathering file list..." - LIST_FILE=$(mktemp) - - find "${VALID_TARGETS[@]}" -type f \( -name "*.md" -o -name "*.mdx" \) \ - | grep -v "/node_modules/" \ - | grep -v "/docs/_remotes/" \ - | grep -v "/versioned_docs/" \ - | grep -v "/build/" \ - | grep -v "/.git/" \ - | grep -v "/_partials/" \ - | grep -v "/_[^/]*$" \ - > "$LIST_FILE" - - FILE_COUNT=$(wc -l < "$LIST_FILE") - echo "πŸ“Š Found $FILE_COUNT files to scan..." - - if [ "$FILE_COUNT" -eq 0 ]; then - echo "⚠️ No files found. Skipping." - rm "$LIST_FILE" - return - fi - - # 4. RUN LINTERS & CAPTURE - VALE_LOG=$(mktemp) - MDLINT_LOG=$(mktemp) - - # --- Run Vale --- - if command -v vale &> /dev/null; then - echo "πŸ“ Running Vale..." - tr '\n' '\0' < "$LIST_FILE" | xargs -0 -r timeout 2m vale \ - --config "${script_dir}/../docs-linter/.vale.ini" \ - --no-wrap \ - --no-exit \ - > "$VALE_LOG" 2>&1 - fi - - # --- Run Markdownlint --- - if command -v markdownlint &> /dev/null; then - echo "🧹 Running Markdownlint..." - tr '\n' '\0' < "$LIST_FILE" | xargs -0 -r timeout 2m markdownlint \ - --config "${script_dir}/../docs-linter/.markdownlint.json" \ - > "$MDLINT_LOG" 2>&1 || true - fi - - # 5. FORMAT & CLEAN LOGS - VALE_CLEAN=$(mktemp) - sed "s|.*/_remotes/|_remotes/|g" "$VALE_LOG" | sed 's/\x1b\[[0-9;]*m//g' > "$VALE_CLEAN" - - MDLINT_CLEAN=$(mktemp) - sed "s|.*/_remotes/|_remotes/|g" "$MDLINT_LOG" | sed 's/\x1b\[[0-9;]*m//g' | \ - awk -F: ' - $1!=last { if(NR>1)print""; print $1; last=$1 } - { $1=""; print " " substr($0,2) } - ' > "$MDLINT_CLEAN" - - # 6. CALCULATE STATS - V_ERR=$(grep -c "error" "$VALE_CLEAN" || true) - V_WARN=$(grep -c "warning" "$VALE_CLEAN" || true) - V_SUG=$(grep -c "suggestion" "$VALE_CLEAN" || true) - MD_ERR=$(grep -c "^ " "$MDLINT_CLEAN" || true) - - TOTAL_ISSUES=$((V_ERR + V_WARN + V_SUG + MD_ERR)) - - # 7. PRINT SUMMARY REPORT - echo "" - echo "========================================================" - echo "πŸ“Š QUALITY CHECK SUMMARY" - echo "========================================================" - echo " πŸ“„ Files Scanned: $FILE_COUNT" - echo " πŸ›‘ Vale Errors: $V_ERR" - echo " ⚠️ Vale Warnings: $V_WARN" - echo " πŸ’‘ Vale Suggestions: $V_SUG" - echo " 🧹 Markdownlint Issues: $MD_ERR" - echo "--------------------------------------------------------" - echo " 🚨 TOTAL ISSUES: $TOTAL_ISSUES" - echo "========================================================" - echo "" - - if [ "$MD_ERR" -gt 0 ]; then - echo "################### MARKDOWNLINT REPORT ###################" - cat "$MDLINT_CLEAN" - echo "" - fi - - if [ $((V_ERR + V_WARN + V_SUG)) -gt 0 ]; then - echo "####################### VALE REPORT #######################" - cat "$VALE_CLEAN" - - if [ "$MD_ERR" -gt 0 ]; then - echo "πŸ›‘ BUT WAIT! You also have $MD_ERR Markdownlint errors (see above)." - fi - echo "" - fi - - # Cleanup - rm "$LIST_FILE" "$VALE_LOG" "$MDLINT_LOG" "$VALE_CLEAN" "$MDLINT_CLEAN" - - echo "βœ… Quality Checks Complete." -} - -# ============================================================================= -# MAIN EXECUTION -# ============================================================================= -if [ "${CLEAN:-0}" -eq 1 ]; then - echo "CLEAN: removing _remotes contents (preserving package.json)" - find "$script_dir/_remotes" -mindepth 1 -maxdepth 1 ! -name 'package.json' -exec rm -rf {} + -fi - -clone_or_update "https://bitbucket.org/netfoundry/zrok-connector.git" frontdoor "$BRANCH_FRONTDOOR" -clone_or_update "https://bitbucket.org/netfoundry/k8s-on-prem-installations.git" selfhosted "$BRANCH_SELFHOSTED" -clone_or_update "https://github.com/openziti/ziti-doc.git" openziti "$BRANCH_ZITI_DOC" -clone_or_update "https://github.com/netfoundry/zlan.git" zlan "$BRANCH_ZLAN" -clone_or_update "https://github.com/openziti/zrok.git" zrok "$BRANCH_ZROK" -clone_or_update "https://bitbucket.org/netfoundry/platform-doc.git" platform "$BRANCH_PLATFORM" -clone_or_update "https://bitbucket.org/netfoundry/nf-data-connector.git" data-connector "$BRANCH_DATA_CONNECTOR" -clone_or_update "https://bitbucket.org/netfoundry/customer-connect-docs.git" customer-connect "$BRANCH_CUSTOMER_CONNECT" - -echo "Cleaning stale build artifacts from remotes..." -find "$script_dir/_remotes" -type d \( -path "*/docusaurus/build" -o -path "*/docusaurus/.docusaurus" -o -path "*/website/build" -o -path "*/website/.docusaurus" \) -exec rm -rf {} + 2>/dev/null || true - -sync_versioned_remote zrok -sync_versioned_remote openziti - -# --- LINT DOCS --- -lint_docs - -if [ "$LINT_ONLY" -eq 1 ]; then - echo "πŸ›‘ --lint-only specified. Exiting before build." - exit 0 -fi - -# --- BUILD OPENZITI SDK REFERENCE DOCS --- -export SDK_ROOT_TARGET="${script_dir}/static/openziti/reference/developer/sdk" -echo "creating openziti SDK target if necessary at: ${SDK_ROOT_TARGET}" -mkdir -p "${SDK_ROOT_TARGET}" - -# -d = skip docusaurus build (unified-doc does its own build) -"${script_dir}/_remotes/openziti/gendoc.sh" -d "${OTHER_FLAGS[@]}" - -# --- DOCUSAURUS BUILD --- -pushd "${script_dir}" >/dev/null -yarn install - -if [ "${CLEAN:-0}" -eq 1 ]; then - echo "CLEAN: clearing Docusaurus cache" - yarn clear -fi - -now=$(date) -commit=$(git -C "${script_dir}" rev-parse --short HEAD 2>/dev/null || echo "unknown") -printf "%s\n%s\n" "$now" "$commit" > "${script_dir}/static/build-time.txt" - -MINIFY_FLAG="" -if [ -n "${NO_MINIFY:-}" ]; then - MINIFY_FLAG="--no-minify" -fi - -echo "========================================" -echo "DOCUSAURUS BUILD" -echo "========================================" -echo " Output dir: build${BUILD_QUALIFIER}" -echo " Build mask: ${DOCUSAURUS_BUILD_MASK:-0xFF}" -echo " No-minify: ${NO_MINIFY:-false}" -echo "========================================" - -yarn build $MINIFY_FLAG --out-dir "build${BUILD_QUALIFIER}" 2>&1 -popd >/dev/null +exec node "${script_dir}/build-docs.mjs" "$@" diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 7d20acc..2fde111 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -14,8 +14,10 @@ import remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-di import {pluginHotjar, pluginReo} from "@netfoundry/docusaurus-theme/node"; import { consoleLink, + customerconnectLink, frontdoorLink, selfhostedLink, + dataconnectorLink, zlanLink, openzitiLink, zrokLink, @@ -616,8 +618,8 @@ const config: Config = { { href: 'https://openziti.discourse.group/', title: 'Discourse', iconName: 'discourse' }, ], productPickerColumns: [ - { header: 'Cloud SaaS', links: [consoleLink, frontdoorLink] }, - { header: 'Self-Hosted Licensed', links: [selfhostedLink, zlanLink] }, + { header: 'Cloud SaaS', links: [consoleLink, customerconnectLink, dataconnectorLink, frontdoorLink] }, + { header: 'Self-Hosted Licensed', links: [selfhostedLink, zlanLink] }, { header: 'Self-Hosted Open Source', links: [openzitiLink, zrokLink] }, { header: 'AI Gateways', links: [ { diff --git a/unified-doc/package.json b/unified-doc/package.json index e7d1c57..f9116b8 100644 --- a/unified-doc/package.json +++ b/unified-doc/package.json @@ -55,7 +55,7 @@ "@docusaurus/theme-mermaid": "^3.10.1", "@hotjar/browser": "^1.0.9", "@mdx-js/react": "^3.0.0", - "@netfoundry/docusaurus-theme": "^0.16.0", + "@netfoundry/docusaurus-theme": "^0.17.0", "@scalar/docusaurus": "^0.8.13", "algoliasearch": "^5.36.0", "asciinema-player": "^3.10.1", diff --git a/unified-doc/yarn.lock b/unified-doc/yarn.lock index dfa6a89..aa03c3a 100644 --- a/unified-doc/yarn.lock +++ b/unified-doc/yarn.lock @@ -2622,10 +2622,10 @@ "@emnapi/runtime" "^1.5.0" "@tybys/wasm-util" "^0.10.1" -"@netfoundry/docusaurus-theme@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@netfoundry/docusaurus-theme/-/docusaurus-theme-0.16.0.tgz#d27e9f4567f75bc4d3f05783fa80973d7602fb61" - integrity sha512-NC8KCegv5Fqd9hW/U9y2LwRLwhwX1GhGNSRooiUyz/5jRIhGnnhrGYymxJ49d0GI/h04beOSyB+jKbcIPg8ElA== +"@netfoundry/docusaurus-theme@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@netfoundry/docusaurus-theme/-/docusaurus-theme-0.17.0.tgz#a88df7a8aecb4164b99adeb3c292e4095aca83d6" + integrity sha512-vGzh9OYeDfyskdqsX/EpFSE4oTc9+8fO2v9NuRGsvfegv2d+swZWLQ2xl+FIvuoEW2Vr+oMu1ytrjQGyXuKQxw== dependencies: "@docsearch/react" "^3" algoliasearch "^5" From 51af04a61cf7f594073fe7058575fd92306a223d Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 07:52:17 -0400 Subject: [PATCH 07/21] fix product picker for 0.17 theme --- unified-doc/docusaurus.config.ts | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/unified-doc/docusaurus.config.ts b/unified-doc/docusaurus.config.ts index 2fde111..41b4628 100644 --- a/unified-doc/docusaurus.config.ts +++ b/unified-doc/docusaurus.config.ts @@ -12,16 +12,7 @@ import { } from "@netfoundry/docusaurus-theme/plugins"; import remarkGithubAdmonitionsToDirectives from "remark-github-admonitions-to-directives"; import {pluginHotjar, pluginReo} from "@netfoundry/docusaurus-theme/node"; -import { - consoleLink, - customerconnectLink, - frontdoorLink, - selfhostedLink, - dataconnectorLink, - zlanLink, - openzitiLink, - zrokLink, -} from "@netfoundry/docusaurus-theme"; +import {unifiedPickerColumns} from "@netfoundry/docusaurus-theme"; import {PublishConfig} from 'src/components/docusaurus' import {zrokDocsPluginConfig, zrokRedirects} from "./_remotes/zrok/website/docusaurus-plugin-zrok-docs.ts"; import {onpremRedirects} from "./_remotes/selfhosted/docusaurus/docusaurus-plugin-onprem-docs.ts"; @@ -618,9 +609,7 @@ const config: Config = { { href: 'https://openziti.discourse.group/', title: 'Discourse', iconName: 'discourse' }, ], productPickerColumns: [ - { header: 'Cloud SaaS', links: [consoleLink, customerconnectLink, dataconnectorLink, frontdoorLink] }, - { header: 'Self-Hosted Licensed', links: [selfhostedLink, zlanLink] }, - { header: 'Self-Hosted Open Source', links: [openzitiLink, zrokLink] }, + ...unifiedPickerColumns, { header: 'AI Gateways', links: [ { label: 'LLM Gateway', From 073502169f6ba62cd99976aaf219c7d049f0a11a Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 08:11:19 -0400 Subject: [PATCH 08/21] use main for cust connect --- unified-doc/build-docs.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unified-doc/build-docs.mjs b/unified-doc/build-docs.mjs index d2fcce6..60a3d61 100644 --- a/unified-doc/build-docs.mjs +++ b/unified-doc/build-docs.mjs @@ -139,7 +139,7 @@ const branches = { zlan : "main", platform : "main", dataConnector : "main", - customerConnect: "add-docs", + customerConnect: "main", }; const BRANCH_FLAG = { "--ziti-doc-branch": "zitiDoc", From f98f6d4ddd583bffec7b469e02959665aabb6f57 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 08:14:56 -0400 Subject: [PATCH 09/21] update caniuse-lite --- unified-doc/yarn.lock | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/unified-doc/yarn.lock b/unified-doc/yarn.lock index aa03c3a..3455939 100644 --- a/unified-doc/yarn.lock +++ b/unified-doc/yarn.lock @@ -4599,15 +4599,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001733: - version "1.0.30001766" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz" - integrity sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA== - -caniuse-lite@^1.0.30001782: - version "1.0.30001792" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz#ca8bb9be244835a335e2018272ce7223691873c5" - integrity sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001702, caniuse-lite@^1.0.30001733, caniuse-lite@^1.0.30001782: + version "1.0.30001806" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz" + integrity sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw== castable-video@~1.1.10: version "1.1.10" From b395da4c28989629b909e9c36f0bf4e7841a4cfe Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:04:18 -0400 Subject: [PATCH 10/21] start trying to clean up local linter violations too --- docs-linter/.markdownlint.json | 2 ++ unified-doc/docs/intro.md | 2 +- unified-doc/docs/llm-gateway/api-keys.md | 2 +- unified-doc/docs/llm-gateway/configuration.md | 2 +- unified-doc/docs/llm-gateway/connect-zrok.md | 4 ++-- unified-doc/docs/llm-gateway/intro.md | 1 - unified-doc/docs/llm-gateway/providers.md | 2 +- unified-doc/docs/llm-gateway/semantic-routing.md | 6 +++--- unified-doc/docs/llm-gateway/streaming.md | 2 +- unified-doc/docs/mcp-gateway/intro.md | 1 - 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs-linter/.markdownlint.json b/docs-linter/.markdownlint.json index 6c324be..31fc513 100644 --- a/docs-linter/.markdownlint.json +++ b/docs-linter/.markdownlint.json @@ -5,6 +5,8 @@ "MD033": false, // Inline HTML. Essential for Docusaurus features (tabs, admonitions, specialized formatting). "MD034": false, // Bare URLs (e.g. https://example.com) without . Common in quickstart guides. "MD009": false, // Trailing spaces. Flags every invisible space at the end of a line. Huge noise source. + "MD010": { "code_blocks": false }, // Hard tabs. Allowed inside code blocks -- Go, Makefiles use real tabs. + "MD025": { "front_matter_title": "" }, // Don't count frontmatter title as an H1; Docusaurus docs use frontmatter title + one body H1. "MD060": false, // Table column style. Flags tables that aren't perfectly ASCII-aligned in the raw text file. Purely visual. "MD041": false // First line heading. Fires on every Docusaurus category index page (MDX imports before any heading). } \ No newline at end of file diff --git a/unified-doc/docs/intro.md b/unified-doc/docs/intro.md index e2feae2..a3be402 100644 --- a/unified-doc/docs/intro.md +++ b/unified-doc/docs/intro.md @@ -2,4 +2,4 @@ sidebar_position: 1 --- -# Empty Page \ No newline at end of file +# Empty Page diff --git a/unified-doc/docs/llm-gateway/api-keys.md b/unified-doc/docs/llm-gateway/api-keys.md index 690efa6..60287a2 100644 --- a/unified-doc/docs/llm-gateway/api-keys.md +++ b/unified-doc/docs/llm-gateway/api-keys.md @@ -65,7 +65,7 @@ Keys are stored as plaintext in the config file, consistent with how upstream AP Every incoming request passes through the auth middleware before reaching any handler: -``` +```text Client request | v diff --git a/unified-doc/docs/llm-gateway/configuration.md b/unified-doc/docs/llm-gateway/configuration.md index 3e2c6d7..75957ce 100644 --- a/unified-doc/docs/llm-gateway/configuration.md +++ b/unified-doc/docs/llm-gateway/configuration.md @@ -165,7 +165,7 @@ llm-gateway run config.yaml ## CLI flags -``` +```text llm-gateway run [flags] Flags: diff --git a/unified-doc/docs/llm-gateway/connect-zrok.md b/unified-doc/docs/llm-gateway/connect-zrok.md index 19cf848..6106cbe 100644 --- a/unified-doc/docs/llm-gateway/connect-zrok.md +++ b/unified-doc/docs/llm-gateway/connect-zrok.md @@ -18,7 +18,7 @@ Both use zrok's overlay network built on [OpenZiti](https://openziti.io). The gateway requires a zrok environment on the host machine. If `zrok enable` hasn't been run, the gateway fails at startup: -``` +```text zrok environment is not enabled; run 'zrok enable' first ``` @@ -50,7 +50,7 @@ An ephemeral share is created at startup and deleted when the gateway shuts down 2. Start the gateway. The share token is logged at startup: - ``` + ```text serving via zrok share 'abc123def456' ``` diff --git a/unified-doc/docs/llm-gateway/intro.md b/unified-doc/docs/llm-gateway/intro.md index be10c23..04b785e 100644 --- a/unified-doc/docs/llm-gateway/intro.md +++ b/unified-doc/docs/llm-gateway/intro.md @@ -45,4 +45,3 @@ translated to and from OpenAI format, so existing tools that speak OpenAI work w Prometheus metrics track request volume, latency, token usage, routing decisions, and endpoint health. Per-request body logging is available for debugging routing behavior. - diff --git a/unified-doc/docs/llm-gateway/providers.md b/unified-doc/docs/llm-gateway/providers.md index 6cbea18..ba9dd97 100644 --- a/unified-doc/docs/llm-gateway/providers.md +++ b/unified-doc/docs/llm-gateway/providers.md @@ -13,7 +13,7 @@ Anthropic, and a local/self-hosted provider for any backend that implements `/v1 All clients interact with the gateway using the [OpenAI chat completions format](https://developers.openai.com/api/reference/chat-completions/overview): -``` +```text POST /v1/chat/completions chat completions (streaming and non-streaming) GET /v1/models list available models from all providers GET /health health check diff --git a/unified-doc/docs/llm-gateway/semantic-routing.md b/unified-doc/docs/llm-gateway/semantic-routing.md index d7c368d..3efa4a0 100644 --- a/unified-doc/docs/llm-gateway/semantic-routing.md +++ b/unified-doc/docs/llm-gateway/semantic-routing.md @@ -15,7 +15,7 @@ falls back to a configured default route. The router evaluates layers in order and stops at the first confident result: -``` +```text Request arrives | v @@ -38,7 +38,7 @@ Request arrives Each step appends to a **cascade log** visible in the gateway's output: -``` +```text semantic routing: method=semantic route='coding' model='claude-haiku-4-5-20251001' confidence=0.87 latency=12ms cascade=[heuristic:no_match,semantic:coding:0.87] ``` @@ -182,7 +182,7 @@ Three modes control how the embedding layer compares a request against stored ro ### Thresholds -``` +```text score >= threshold β†’ confident match, return immediately ambiguous_threshold <= score < threshold β†’ ambiguous, escalate to classifier score < ambiguous_threshold β†’ no match, continue to next layer diff --git a/unified-doc/docs/llm-gateway/streaming.md b/unified-doc/docs/llm-gateway/streaming.md index 519cd81..963ed0b 100644 --- a/unified-doc/docs/llm-gateway/streaming.md +++ b/unified-doc/docs/llm-gateway/streaming.md @@ -58,7 +58,7 @@ for chunk in stream: The gateway returns a series of SSE events. Each chunk follows the OpenAI format: -``` +```text data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":"Quantum"},"index":0}]} data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","choices":[{"delta":{"content":" entanglement"},"index":0}]} diff --git a/unified-doc/docs/mcp-gateway/intro.md b/unified-doc/docs/mcp-gateway/intro.md index ef4d93d..3ba3bbc 100644 --- a/unified-doc/docs/mcp-gateway/intro.md +++ b/unified-doc/docs/mcp-gateway/intro.md @@ -56,4 +56,3 @@ backend connections β€” no shared state, no cross-talk between sessions. ```bash mcp-tools run a1b2c3d4e5f6 ``` - From c109e931a5f39f223b976ad32da9f2cbacb4fa44 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:20:15 -0400 Subject: [PATCH 11/21] fixing linter one bucket at a time --- CONTRIBUTING.md | 54 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 01b638c..0a58fa5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,9 +2,9 @@ This guide covers the development workflow for making changes to the NetFoundry Docusaurus theme and shared components. -## Repository Structure +## Repository structure -``` +```text docusaurus-shared/ β”œβ”€β”€ packages/ β”‚ └── docusaurus-theme/ # @netfoundry/docusaurus-theme @@ -36,7 +36,7 @@ docusaurus-shared/ └── CONTRIBUTING.md # You are here ``` -## The Theme Package +## The theme package | Package | npm | Purpose | |---------|-----|---------| @@ -44,14 +44,14 @@ docusaurus-shared/ --- -## Development Workflow +## Development workflow ### Prerequisites - Node.js 18+ - Yarn package manager -### Initial Setup +### Initial setup ```bash git clone https://github.com/netfoundry/docusaurus-shared.git @@ -59,7 +59,7 @@ cd docusaurus-shared yarn install ``` -### Quick Commands (from repo root) +### Quick commands (from repo root) ```bash yarn dev # Start test-site dev server @@ -69,9 +69,9 @@ yarn test # Run theme tests --- -## Making Changes to the Theme +## Making changes to the theme -### 1. Configure Local Development +### 1. Configure local development The test-site is pre-configured to use the local theme. Check `test-site/docusaurus.config.ts`: @@ -89,7 +89,7 @@ export default { }; ``` -### 2. Start Development Server +### 2. Start development server ```bash yarn dev @@ -99,7 +99,7 @@ cd test-site && yarn start Open http://localhost:3000. Changes to theme files hot-reload automatically. -### 3. Make Your Changes +### 3. Make your changes Common file locations: @@ -115,7 +115,7 @@ Common file locations: | Remark plugins | `packages/docusaurus-theme/src/docusaurus-plugins/` | | Theme config types | `packages/docusaurus-theme/src/options.ts` | -### 4. Test Your Changes +### 4. Test your changes ```bash # Development server (hot reload) @@ -126,7 +126,7 @@ yarn build cd test-site && yarn serve ``` -### 5. Run Tests +### 5. Run tests ```bash yarn test @@ -146,14 +146,16 @@ npm version patch # 0.1.2 β†’ 0.1.3 npm publish ``` -### 7. Verify Published Package +### 7. Verify published package Update `test-site/package.json`: + ```json "@netfoundry/docusaurus-theme": "^0.1.3" ``` Switch `test-site/docusaurus.config.ts` to use package name: + ```typescript themes: [ '@netfoundry/docusaurus-theme', @@ -161,6 +163,7 @@ themes: [ ``` Then: + ```bash cd test-site yarn install @@ -169,22 +172,23 @@ yarn build --- -## Example: Changing a CSS Variable +## Example: Changing a CSS variable Here's a complete walkthrough of changing the light-mode tab color. -### The Problem +### The problem The tab highlight color (`--nf-tab-color`) is pink in light mode. We want grey instead. -### Step 1: Find the Variable +### Step 1: Find the variable ```bash grep -n "nf-tab-color" packages/docusaurus-theme/css/legacy.css ``` Output: -``` + +```text 89: --nf-tab-color: 255, 182, 193; 90: --nf-tab-color-render: rgb(255, 182, 193); 143: --nf-tab-color: 67, 72, 98; @@ -193,13 +197,13 @@ Output: - Line 89-90: Light mode (`:root`) - Line 143: Dark mode (`html[data-theme="dark"]`) -### Step 2: Start Dev Server +### Step 2: Start dev server ```bash yarn dev ``` -### Step 3: Make the Change +### Step 3: Make the change Edit `packages/docusaurus-theme/css/legacy.css` around line 89: @@ -219,11 +223,11 @@ Edit `packages/docusaurus-theme/css/legacy.css` around line 89: Save. Browser hot-reloads with new color. -### Step 4: Test Dark Mode +### Step 4: Test dark mode Toggle dark mode in browser. Dark mode uses a different value (line 143) - verify it still looks correct. -### Step 5: Run Tests & Build +### Step 5: Run tests & build ```bash yarn test @@ -238,13 +242,13 @@ npm version patch npm publish ``` -### Step 7: Final Verification +### Step 7: Final verification Update `test-site/package.json` to new version, switch config to package name, reinstall, rebuild. --- -## CSS Variable Reference +## CSS variable reference Key variables in `packages/docusaurus-theme/css/legacy.css`: @@ -259,7 +263,7 @@ Key variables in `packages/docusaurus-theme/css/legacy.css`: --- -## Testing Checklist +## Testing checklist Before publishing: @@ -304,7 +308,7 @@ The theme ships source files. Fix errors in theme source, not consumers. --- -## Package Entry Points +## Package entry points The theme exposes multiple entry points: From 315de2f904566428bb669c4d969a3f11cb06a21c Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:23:12 -0400 Subject: [PATCH 12/21] fixing linter one bucket at a time --- packages/docusaurus-theme/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-theme/README.md b/packages/docusaurus-theme/README.md index 78b9c70..7ee6161 100644 --- a/packages/docusaurus-theme/README.md +++ b/packages/docusaurus-theme/README.md @@ -57,16 +57,20 @@ export default { ## What's Included -### Automatic Layout +### Automatic layout + The theme automatically provides: + - **NetFoundry Layout** - Wraps all pages with consistent structure - **Footer** - Configurable footer with social links and site sections - **Star Banner** - Optional GitHub star call-to-action banner -### CSS Variables & Styling +### CSS variables & styling + All CSS is automatically loaded. No need to add `@import` statements to your `custom.css`. Includes: + - NetFoundry brand colors and typography - Light/dark mode support - Responsive design tokens @@ -80,7 +84,7 @@ Import UI components directly: import { Alert, CodeBlock, OsTabs } from '@netfoundry/docusaurus-theme/ui'; ``` -### Remark Plugins +### Remark plugins Import remark plugins for your docs config: @@ -98,7 +102,7 @@ export default { }; ``` -### Node Utilities +### Node utilities Import Node.js utilities: @@ -106,7 +110,7 @@ Import Node.js utilities: import { pluginHotjar, cleanUrl, docUrl } from '@netfoundry/docusaurus-theme/node'; ``` -## Package Exports +## Package exports | Export | Description | |--------|-------------| @@ -118,7 +122,7 @@ import { pluginHotjar, cleanUrl, docUrl } from '@netfoundry/docusaurus-theme/nod ## Customization -### Swizzling Components +### Swizzling components To customize the layout beyond configuration: From ab62c72a19b2640fade531a51c2fe8dd3a4c7b4f Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:24:49 -0400 Subject: [PATCH 13/21] fixing linter one bucket at a time --- packages/LOCAL-DEV.md | 10 +++++----- packages/test-site/docs/code-theme/java-csharp.md | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/LOCAL-DEV.md b/packages/LOCAL-DEV.md index 04ad442..b8689e8 100644 --- a/packages/LOCAL-DEV.md +++ b/packages/LOCAL-DEV.md @@ -1,10 +1,10 @@ -# Local Development Guide +# Local development guide How to develop and test the theme locally before publishing to npm. ## Overview -``` +```text β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ test-site/ β”‚ β”‚ file: protocol β”‚ β”‚ npm install β”‚ β”‚ (yarn link) β”‚ --> β”‚ (simulates npm) β”‚ --> β”‚ (production) β”‚ @@ -14,7 +14,7 @@ How to develop and test the theme locally before publishing to npm. ## Project layout -``` +```text packages/ β”œβ”€β”€ docusaurus-theme/ # @netfoundry/docusaurus-theme npm package β”‚ β”œβ”€β”€ src/ # TypeScript source β†’ compiled to dist/ @@ -115,7 +115,7 @@ yarn build This compiles TypeScript to CommonJS in `dist/`. -## Step 4: Test with remote site (file: protocol) +## Step 4: Test with remote site (`file:` protocol) This simulates exactly what npm publish will deliver. @@ -208,7 +208,7 @@ yarn build Each sub-project in `remotes/` follows the same pattern as the real repos: -``` +```text remotes/zrok/website/ β”œβ”€β”€ docusaurus.config.ts # Standalone config (references local theme) β”œβ”€β”€ docusaurus-plugin-zrok-docs.ts # Plugin config for aggregation diff --git a/packages/test-site/docs/code-theme/java-csharp.md b/packages/test-site/docs/code-theme/java-csharp.md index 1d181ca..0bab504 100644 --- a/packages/test-site/docs/code-theme/java-csharp.md +++ b/packages/test-site/docs/code-theme/java-csharp.md @@ -2,7 +2,7 @@ sidebar_label: "Java & C#" --- -# Theme test: Java and C# +# Theme test: Java and C\# ## Java @@ -44,7 +44,7 @@ public final class OverlayClient { } ``` -## C# +## C\# ```csharp using System; From 88c67fa0a2bc58646f7febdcca408e17fa75c76a Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:34:35 -0400 Subject: [PATCH 14/21] fixing linter one bucket at a time --- .github/workflows/vale-check.yml | 5 ++++- docs-linter/.markdownlint.json | 2 ++ docs-linter/.vale.ini | 3 +++ packages/test-site/docs/components/tab-groups.mdx | 14 +++++++++++--- packages/test-site/docs/markdown/admonitions.mdx | 3 +++ packages/test-site/docs/markdown/code-blocks.mdx | 7 ++++--- packages/test-site/docs/markdown/typography.mdx | 6 ++++-- 7 files changed, 31 insertions(+), 9 deletions(-) diff --git a/.github/workflows/vale-check.yml b/.github/workflows/vale-check.yml index b15dc41..44344cc 100644 --- a/.github/workflows/vale-check.yml +++ b/.github/workflows/vale-check.yml @@ -1,6 +1,9 @@ name: Lint Docs -on: [push, pull_request] +on: + pull_request: + push: + branches: [main] jobs: lint: diff --git a/docs-linter/.markdownlint.json b/docs-linter/.markdownlint.json index 31fc513..778eaf2 100644 --- a/docs-linter/.markdownlint.json +++ b/docs-linter/.markdownlint.json @@ -7,6 +7,8 @@ "MD009": false, // Trailing spaces. Flags every invisible space at the end of a line. Huge noise source. "MD010": { "code_blocks": false }, // Hard tabs. Allowed inside code blocks -- Go, Makefiles use real tabs. "MD025": { "front_matter_title": "" }, // Don't count frontmatter title as an H1; Docusaurus docs use frontmatter title + one body H1. + "MD028": false, // Blank line between consecutive blockquotes -- legit for stacked GitHub-style admonitions. + "MD030": { "ol_single": 2, "ol_multi": 2 }, // Ordered lists use 2 spaces after the marker (4-space content indent, per nf-style-guide). "MD060": false, // Table column style. Flags tables that aren't perfectly ASCII-aligned in the raw text file. Purely visual. "MD041": false // First line heading. Fires on every Docusaurus category index page (MDX imports before any heading). } \ No newline at end of file diff --git a/docs-linter/.vale.ini b/docs-linter/.vale.ini index 4aa2b3c..fc44104 100644 --- a/docs-linter/.vale.ini +++ b/docs-linter/.vale.ini @@ -17,3 +17,6 @@ Microsoft.Contractions = NO Microsoft.FirstPerson = NO Microsoft.HeadingPunctuation = NO Microsoft.Dashes = NO +Microsoft.Auto = NO +Microsoft.Spacing = NO +Microsoft.Ellipses = NO diff --git a/packages/test-site/docs/components/tab-groups.mdx b/packages/test-site/docs/components/tab-groups.mdx index 8557f93..62319ed 100644 --- a/packages/test-site/docs/components/tab-groups.mdx +++ b/packages/test-site/docs/components/tab-groups.mdx @@ -6,8 +6,6 @@ import TabItem from '@theme/TabItem'; Demonstrates the `` / `` MDX components and how the active tab group is styled by the various `tabs-v*.css` themes in `@netfoundry/docusaurus-theme/css/`. - - @ ``` + -- Once the VM is created, we can get the IP address of the VM from the Instance(s) screen. +- Once the VM is created, we can get the IP address of the VM from the Instances screen. Login to the VM by using user name "ubuntu": + ```text ssh -i ubuntu@ ``` + @@ -44,25 +46,31 @@ ssh -i ubuntu@ - Once the VM is created, get the IP address of the droplet from the Resources screen. Login to the VM by using user "root" and IP address: + ```text ssh root@ ``` + - Once the VM is created, we can get the IP address of the VM from the instance details screen. - Login to the VM by using user name "ubuntu" and the IP address: + ```text ssh -i ubuntu@ ``` + - Once the VM is created, we can get the IP address of the VM from the Devices screen. - Login to the VM by using user name "ubuntu" and the IP address: + ```text ssh -i ubuntu@ ``` + diff --git a/packages/test-site/docs/markdown/admonitions.mdx b/packages/test-site/docs/markdown/admonitions.mdx index 358ff61..02ffcb0 100644 --- a/packages/test-site/docs/markdown/admonitions.mdx +++ b/packages/test-site/docs/markdown/admonitions.mdx @@ -60,6 +60,7 @@ After running, verify `$ZITI_HOME` is set. ::: :::tip + ```yaml site: name: MySite @@ -68,6 +69,7 @@ site: - search - analytics ``` + ::: ## Admonition with a table @@ -86,6 +88,7 @@ Make sure none of these are in use before continuing. ## Admonition with a button (raw HTML) :::danger[Danger button] + ```sh rm -rf / ``` diff --git a/packages/test-site/docs/markdown/code-blocks.mdx b/packages/test-site/docs/markdown/code-blocks.mdx index 7a99bde..7451964 100644 --- a/packages/test-site/docs/markdown/code-blocks.mdx +++ b/packages/test-site/docs/markdown/code-blocks.mdx @@ -74,7 +74,7 @@ $ ziti edge list services ## Plain (no language) block -``` +```text plain text fence preserves whitespace and renders without syntax highlighting @@ -194,7 +194,7 @@ line 20 * a bullet introducing a code block - ``` + ```text code at the indented level second line of code ``` @@ -202,9 +202,10 @@ line 20 :::note A note next to the code block, both indented under the bullet: - ``` + ```text code inside a note inside a list item ``` + ::: * another bullet for spacing diff --git a/packages/test-site/docs/markdown/typography.mdx b/packages/test-site/docs/markdown/typography.mdx index 1f6ea24..c7b756d 100644 --- a/packages/test-site/docs/markdown/typography.mdx +++ b/packages/test-site/docs/markdown/typography.mdx @@ -1,4 +1,6 @@ -# Typography reference +--- +title: Typography reference +--- A single page that exercises every text-level Markdown feature so you can spot regressions in `legacy.css` or the IFM defaults. @@ -77,7 +79,7 @@ H2O is subscript; E = mc2 uses superscript. - Another bullet 2. Numbered step two - Bulleted sub-point with `inline code` - - Bulleted sub-point with a [link](https://example.com) + - Bulleted sub-point with a [sample link](https://example.com) ### Task lists From 0a63694dd732822fb5ebb9fbb7c71ce5e41fdd60 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:42:21 -0400 Subject: [PATCH 15/21] fixing linter one bucket at a time --- CONTRIBUTING.md | 12 ++--- packages/test-site/README.md | 24 ++++----- .../docs/components/product-search.mdx | 16 +++--- .../test-site/docs/markdown/admonitions.mdx | 12 ++--- .../test-site/docs/markdown/code-blocks.mdx | 16 +++--- .../test-site/docs/plugins/openapi-scalar.mdx | 30 +++++------ skills/doc-check/SKILL.md | 54 +++++++++---------- unified-doc/README.md | 10 ++-- unified-doc/docs/llm-gateway/configuration.md | 16 +++--- unified-doc/docs/llm-gateway/connect-zrok.md | 6 +-- unified-doc/docs/llm-gateway/get-started.md | 34 ++++++------ unified-doc/docs/llm-gateway/streaming.md | 12 ++--- unified-doc/docs/mcp-gateway/intro.md | 4 +- .../docs/mcp-gateway/persistent-shares.md | 6 +-- 14 files changed, 126 insertions(+), 126 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a58fa5..375a7c9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -292,15 +292,15 @@ Also verify `docusaurus.config.ts` uses local path, not package name. ### Module not found? -1. Run `yarn install` from repo root -2. Check the file exists at the path specified in `package.json` exports -3. Restart dev server +1. Run `yarn install` from repo root +2. Check the file exists at the path specified in `package.json` exports +3. Restart dev server ### CSS not loading? -1. Check `css/theme.css` imports the file you changed -2. Verify `src/index.ts` `getClientModules()` includes `theme.css` -3. Hard refresh browser (Ctrl+Shift+R) +1. Check `css/theme.css` imports the file you changed +2. Verify `src/index.ts` `getClientModules()` includes `theme.css` +3. Hard refresh browser (Ctrl+Shift+R) ### TypeScript errors in consuming project? diff --git a/packages/test-site/README.md b/packages/test-site/README.md index 40f09a4..a1c6392 100644 --- a/packages/test-site/README.md +++ b/packages/test-site/README.md @@ -111,10 +111,10 @@ category landing page **and** in the sidebar. No `sidebars.ts` edit needed. ## Adding a new sample page -1. Pick the right folder (or add a new one with a fresh `_category_.json`). -2. Drop in a `.mdx` file. Frontmatter is optional; use `sidebar_position` if - you want to influence ordering. -3. Save. The dev server picks it up. +1. Pick the right folder (or add a new one with a fresh `_category_.json`). +2. Drop in a `.mdx` file. Frontmatter is optional; use `sidebar_position` if + you want to influence ordering. +3. Save. The dev server picks it up. For something that exists in the theme package but doesn't have a demo here, the test-site is the right place for it -- not in any downstream site. @@ -135,14 +135,14 @@ inline backticks. Two things to check: -1. You edited the right file. Shared rules belong in - `packages/docusaurus-theme/css/`, **not** in `packages/test-site/src/custom/custom.css`. - See [CSS conventions](../../CLAUDE.md#css-conventions) (or whichever file - you have in front of you). -2. The dev server is actually watching it. The `getClientModules()` path - trick (`'../../css/theme.css'`) means edits to `css/*.css` propagate - without a theme rebuild. If they don't, restart the test-site server -- a - stale Webpack cache is the usual culprit. +1. You edited the right file. Shared rules belong in + `packages/docusaurus-theme/css/`, **not** in `packages/test-site/src/custom/custom.css`. + See [CSS conventions](../../CLAUDE.md#css-conventions) (or whichever file + you have in front of you). +2. The dev server is actually watching it. The `getClientModules()` path + trick (`'../../css/theme.css'`) means edits to `css/*.css` propagate + without a theme rebuild. If they don't, restart the test-site server -- a + stale Webpack cache is the usual culprit. ### "I edited a React component and nothing changed" diff --git a/packages/test-site/docs/components/product-search.mdx b/packages/test-site/docs/components/product-search.mdx index b0d1674..003ca8b 100644 --- a/packages/test-site/docs/components/product-search.mdx +++ b/packages/test-site/docs/components/product-search.mdx @@ -43,11 +43,11 @@ import {useCustomFields} from '@netfoundry/docusaurus-theme/ui'; ## What to verify when wiring it up -1. Search box renders and accepts input. -2. Hits stream in as you type (no submit needed). -3. Product filter chips reflect the `products` prop. -4. Pagination renders at the bottom of the results list. -5. The "Powered by Algolia" badge appears. -6. Clicking a hit navigates to the matching doc URL (`url_without_anchor` + - `anchor` are honored). -7. Snippets highlight matched terms within the result body. +1. Search box renders and accepts input. +2. Hits stream in as you type (no submit needed). +3. Product filter chips reflect the `products` prop. +4. Pagination renders at the bottom of the results list. +5. The "Powered by Algolia" badge appears. +6. Clicking a hit navigates to the matching doc URL (`url_without_anchor` + + `anchor` are honored). +7. Snippets highlight matched terms within the result body. diff --git a/packages/test-site/docs/markdown/admonitions.mdx b/packages/test-site/docs/markdown/admonitions.mdx index 02ffcb0..bbd9ee6 100644 --- a/packages/test-site/docs/markdown/admonitions.mdx +++ b/packages/test-site/docs/markdown/admonitions.mdx @@ -140,14 +140,14 @@ you can import a README that uses `> [!NOTE]` syntax and it renders correctly. ## Admonition inside a list -1. First step. -2. Second step. +1. First step. +2. Second step. - :::warning - This admonition is indented as a list-item child. - ::: + :::warning + This admonition is indented as a list-item child. + ::: -3. Third step. +3. Third step. ## Nested admonitions diff --git a/packages/test-site/docs/markdown/code-blocks.mdx b/packages/test-site/docs/markdown/code-blocks.mdx index 7451964..37120c5 100644 --- a/packages/test-site/docs/markdown/code-blocks.mdx +++ b/packages/test-site/docs/markdown/code-blocks.mdx @@ -212,17 +212,17 @@ line 20 ## Code in an ordered list -1. Run the install command: +1. Run the install command: - ```bash - curl -sSf https://get.openziti.io/install.bash | sudo bash - ``` + ```bash + curl -sSf https://get.openziti.io/install.bash | sudo bash + ``` -2. Verify: +2. Verify: - ```bash - ziti version - ``` + ```bash + ziti version + ``` ## Code in a table cell diff --git a/packages/test-site/docs/plugins/openapi-scalar.mdx b/packages/test-site/docs/plugins/openapi-scalar.mdx index b2aac10..77f9a91 100644 --- a/packages/test-site/docs/plugins/openapi-scalar.mdx +++ b/packages/test-site/docs/plugins/openapi-scalar.mdx @@ -35,27 +35,27 @@ import type {ScalarOptions} from '@scalar/docusaurus'; ## Required setup in the consuming site -1. Add the dependency: +1. Add the dependency: - ```json - "dependencies": { - "@scalar/docusaurus": "^0.8.13" - } - ``` + ```json + "dependencies": { + "@scalar/docusaurus": "^0.8.13" + } + ``` -2. Add the Scalar theme stylesheet to `themes` -> `customCss`: +2. Add the Scalar theme stylesheet to `themes` -> `customCss`: - ```ts - require.resolve('@scalar/docusaurus/dist/theme.css'), - ``` + ```ts + require.resolve('@scalar/docusaurus/dist/theme.css'), + ``` -3. Add one plugin entry per API spec (see the table above). +3. Add one plugin entry per API spec (see the table above). -4. Reference the rendered page from your sidebar or from other docs: +4. Reference the rendered page from your sidebar or from other docs: - ```markdown - See the [Edge Client API reference](/docs/openziti/reference/developer/api/edge-client-api-reference). - ``` + ```markdown + See the [Edge Client API reference](/docs/openziti/reference/developer/api/edge-client-api-reference). + ``` ## Why not redocusaurus diff --git a/skills/doc-check/SKILL.md b/skills/doc-check/SKILL.md index 3e84193..0789381 100644 --- a/skills/doc-check/SKILL.md +++ b/skills/doc-check/SKILL.md @@ -11,9 +11,9 @@ then optionally generate a doc draft. Before using this skill, configure it for your organization: -1. **Update the product registry** below with your products, source repos, auth method, and local doc paths. -2. **Set auth environment variables** as needed (see Auth section below). -3. **Update the style guide reference** in step 7 to point to your own documentation style guide. +1. **Update the product registry** below with your products, source repos, auth method, and local doc paths. +2. **Set auth environment variables** as needed (see Auth section below). +3. **Update the style guide reference** in step 7 to point to your own documentation style guide. ## Invocation @@ -268,30 +268,30 @@ After the report, prompt: When `--draft ` is passed: -1. Fetch the PR title, description, and full diff from the specified repo -2. If the status was **stale**, read the existing doc file first β€” the draft should update it, not replace it -3. If the status was **missing**, write a new file from scratch -4. Identify what changed from a user perspective -5. Determine the appropriate doc type (how-to, reference, concept explanation) using DiΓ‘taxis -6. Write the draft following your organization's documentation style guide: - - Sentence-style headers; imperative verb phrases for how-to titles - - Active voice, second person ("you/your") - - Backticks for CLI flags, commands, config keys, code tokens - - 120-character line length limit -7. **Only write what the diff and PR description directly support.** Do not infer, extrapolate, or invent behavior that - isn't shown. If the diff shows a flag exists but not what it does, say so β€” don't guess. If the PR description is - vague or the diff is too large to confidently summarize, stop and ask the user to clarify before drafting. It's - better to ask one question than to ship a plausible-sounding but wrong doc. -8. Present the full draft inline in the terminal, followed by the suggested file path, then prompt the user with these - options: - - > **What would you like to do?** - > - **Execute** β€” write the draft directly to the suggested file path in the doc repo - > - **Edit** β€” describe changes and I'll update the draft before writing - > - **Save to drafts** β€” save to `output//drafts/--.md` for later without touching the doc repo - - **Do not call Edit or Write on any doc repo file until the user selects "Execute".** Saving to drafts is always safe - and does not require confirmation. +1. Fetch the PR title, description, and full diff from the specified repo +2. If the status was **stale**, read the existing doc file first β€” the draft should update it, not replace it +3. If the status was **missing**, write a new file from scratch +4. Identify what changed from a user perspective +5. Determine the appropriate doc type (how-to, reference, concept explanation) using DiΓ‘taxis +6. Write the draft following your organization's documentation style guide: + - Sentence-style headers; imperative verb phrases for how-to titles + - Active voice, second person ("you/your") + - Backticks for CLI flags, commands, config keys, code tokens + - 120-character line length limit +7. **Only write what the diff and PR description directly support.** Do not infer, extrapolate, or invent behavior that + isn't shown. If the diff shows a flag exists but not what it does, say so β€” don't guess. If the PR description is + vague or the diff is too large to confidently summarize, stop and ask the user to clarify before drafting. It's + better to ask one question than to ship a plausible-sounding but wrong doc. +8. Present the full draft inline in the terminal, followed by the suggested file path, then prompt the user with these + options: + + > **What would you like to do?** + > - **Execute** β€” write the draft directly to the suggested file path in the doc repo + > - **Edit** β€” describe changes and I'll update the draft before writing + > - **Save to drafts** β€” save to `output//drafts/--.md` for later without touching the doc repo + + **Do not call Edit or Write on any doc repo file until the user selects "Execute".** Saving to drafts is always safe + and does not require confirmation. #### Drafts folder diff --git a/unified-doc/README.md b/unified-doc/README.md index 700e51e..b2a4411 100644 --- a/unified-doc/README.md +++ b/unified-doc/README.md @@ -125,11 +125,11 @@ Products: `home`, `openziti`, `frontdoor`, `selfhosted`, `zrok`, `zlan` ### Workflow -1. **Generate scenarios** - Fetches sitemap from production and creates `backstop..json` configs -2. **Capture reference** - Screenshots production site as the baseline -3. **Run tests** - Screenshots local site and compares against reference -4. **Review report** - HTML report shows side-by-side diffs with highlighted changes -5. **Approve changes** - If changes are intentional, approve to update reference +1. **Generate scenarios** - Fetches sitemap from production and creates `backstop..json` configs +2. **Capture reference** - Screenshots production site as the baseline +3. **Run tests** - Screenshots local site and compares against reference +4. **Review report** - HTML report shows side-by-side diffs with highlighted changes +5. **Approve changes** - If changes are intentional, approve to update reference ### Configuration diff --git a/unified-doc/docs/llm-gateway/configuration.md b/unified-doc/docs/llm-gateway/configuration.md index 75957ce..d0130b9 100644 --- a/unified-doc/docs/llm-gateway/configuration.md +++ b/unified-doc/docs/llm-gateway/configuration.md @@ -181,14 +181,14 @@ CLI flags take precedence over the config file. When the gateway starts, it: -1. Loads and parses the YAML config file. -2. Applies any CLI flag overrides. -3. Expands environment variables. -4. Initializes providers (OpenAI, Anthropic, local/self-hosted) in order. -5. Creates the model-to-provider router. -6. Initializes OpenTelemetry metrics (if enabled). -7. Initializes the semantic router (if configured). -8. Starts the HTTP server (local or via zrok share). +1. Loads and parses the YAML config file. +2. Applies any CLI flag overrides. +3. Expands environment variables. +4. Initializes providers (OpenAI, Anthropic, local/self-hosted) in order. +5. Creates the model-to-provider router. +6. Initializes OpenTelemetry metrics (if enabled). +7. Initializes the semantic router (if configured). +8. Starts the HTTP server (local or via zrok share). On shutdown (SIGINT/SIGTERM), the gateway closes all providers, deletes ephemeral zrok shares, and releases zrok access objects before exiting. diff --git a/unified-doc/docs/llm-gateway/connect-zrok.md b/unified-doc/docs/llm-gateway/connect-zrok.md index 6106cbe..34f4824 100644 --- a/unified-doc/docs/llm-gateway/connect-zrok.md +++ b/unified-doc/docs/llm-gateway/connect-zrok.md @@ -33,7 +33,7 @@ to the share token rather than an IP address. An ephemeral share is created at startup and deleted when the gateway shuts down. -1. Add the zrok config to `config.yaml`: +1. Add the zrok config to `config.yaml`: ```yaml zrok: @@ -48,13 +48,13 @@ An ephemeral share is created at startup and deleted when the gateway shuts down llm-gateway run config.yaml --zrok --zrok-mode private ``` -2. Start the gateway. The share token is logged at startup: +2. Start the gateway. The share token is logged at startup: ```text serving via zrok share 'abc123def456' ``` -3. Give clients the share token to connect. +3. Give clients the share token to connect. **Public mode** creates a share accessible by anyone with the token. **Private mode** (the default) requires the client to have a zrok environment enabled and creates an access-controlled connection diff --git a/unified-doc/docs/llm-gateway/get-started.md b/unified-doc/docs/llm-gateway/get-started.md index 41ca409..f48b7fd 100644 --- a/unified-doc/docs/llm-gateway/get-started.md +++ b/unified-doc/docs/llm-gateway/get-started.md @@ -16,19 +16,19 @@ Choose the installation method that fits your environment. Pre-built binaries are available for Linux, macOS, and Windows: -1. Visit the [GitHub Releases](https://github.com/openziti/llm-gateway/releases) page. -2. Download the binary for your platform. -3. Make it executable: +1. Visit the [GitHub Releases](https://github.com/openziti/llm-gateway/releases) page. +2. Download the binary for your platform. +3. Make it executable: - ```bash - chmod +x llm-gateway - ``` + ```bash + chmod +x llm-gateway + ``` -4. Run it: +4. Run it: - ```bash - ./llm-gateway run config.yaml - ``` + ```bash + ./llm-gateway run config.yaml + ``` ### Install with Go @@ -56,26 +56,26 @@ The examples below progress from a simple single-provider proxy to a full produc ### Proxy a local inference server -1. Start Ollama: +1. Start Ollama: ```bash ollama serve ``` -2. Create `config.yaml`: +2. Create `config.yaml`: ```yaml local: base_url: http://localhost:11434 ``` -3. Start the gateway: +3. Start the gateway: ```bash llm-gateway run config.yaml ``` -4. Send a request: +4. Send a request: ```bash curl -X POST http://localhost:8080/v1/chat/completions \ @@ -127,14 +127,14 @@ curl -X POST http://localhost:8080/v1/chat/completions \ ### Restrict API access with virtual keys -1. Generate an API key: +1. Generate an API key: ```bash llm-gateway genkey # sk-gw-a1b2c3d4e5f6... ``` -2. Add `api_keys` to your config, referencing the key and setting per-key model permissions: +2. Add `api_keys` to your config, referencing the key and setting per-key model permissions: ```yaml api_keys: @@ -158,7 +158,7 @@ curl -X POST http://localhost:8080/v1/chat/completions \ base_url: http://localhost:11434 ``` -3. Clients send their key in the `Authorization` header: +3. Clients send their key in the `Authorization` header: ```bash curl -X POST http://localhost:8080/v1/chat/completions \ diff --git a/unified-doc/docs/llm-gateway/streaming.md b/unified-doc/docs/llm-gateway/streaming.md index 963ed0b..95a51ee 100644 --- a/unified-doc/docs/llm-gateway/streaming.md +++ b/unified-doc/docs/llm-gateway/streaming.md @@ -11,12 +11,12 @@ All providers support streaming chat completions via Server-Sent Events (SSE). When the client sends `"stream": true`, the gateway: -1. Sends the request to the upstream provider with streaming enabled. -2. Sets SSE response headers (`Content-Type: text/event-stream`, `Cache-Control: no-cache`, - `X-Accel-Buffering: no`). -3. Reads chunks from the provider as they arrive. -4. Writes each chunk as a `data: {json}\n\n` SSE event and flushes immediately. -5. Sends `data: [DONE]\n\n` when the stream completes. +1. Sends the request to the upstream provider with streaming enabled. +2. Sets SSE response headers (`Content-Type: text/event-stream`, `Cache-Control: no-cache`, + `X-Accel-Buffering: no`). +3. Reads chunks from the provider as they arrive. +4. Writes each chunk as a `data: {json}\n\n` SSE event and flushes immediately. +5. Sends `data: [DONE]\n\n` when the stream completes. ## Send a streaming request diff --git a/unified-doc/docs/mcp-gateway/intro.md b/unified-doc/docs/mcp-gateway/intro.md index 3ba3bbc..98bcf4a 100644 --- a/unified-doc/docs/mcp-gateway/intro.md +++ b/unified-doc/docs/mcp-gateway/intro.md @@ -41,7 +41,7 @@ backend connections β€” no shared state, no cross-talk between sessions. ## Quick example -1. Share a local MCP server over the overlay: +1. Share a local MCP server over the overlay: ```bash mcp-bridge mcp-filesystem ~/Documents @@ -51,7 +51,7 @@ backend connections β€” no shared state, no cross-talk between sessions. {"share_token":"a1b2c3d4e5f6"} ``` -2. Connect to it from anywhere with a zrok-enabled environment: +2. Connect to it from anywhere with a zrok-enabled environment: ```bash mcp-tools run a1b2c3d4e5f6 diff --git a/unified-doc/docs/mcp-gateway/persistent-shares.md b/unified-doc/docs/mcp-gateway/persistent-shares.md index 7be183b..1ce04d0 100644 --- a/unified-doc/docs/mcp-gateway/persistent-shares.md +++ b/unified-doc/docs/mcp-gateway/persistent-shares.md @@ -8,7 +8,7 @@ sidebar_label: Persistent shares By default, share tokens are ephemeral β€” they disappear when the process exits. For production use, create persistent shares that survive restarts and keep a stable token. -1. Create a persistent share by running this once to reserve a named token: +1. Create a persistent share by running this once to reserve a named token: ```bash zrok2 create share my-gateway @@ -17,7 +17,7 @@ create persistent shares that survive restarts and keep a stable token. Share names must be 3–32 characters, lowercase alphanumeric and hyphens (`[a-z0-9-]`). If you omit the name, zrok generates a random token. -2. Reference the token in your config: +2. Reference the token in your config: **mcp-gateway** β€” set `share_token` at the top level: @@ -35,7 +35,7 @@ create persistent shares that survive restarts and keep a stable token. mcp-bridge --share-token my-bridge mcp-filesystem ~/Documents ``` -3. When you no longer need the share, delete it: +3. When you no longer need the share, delete it: ```bash zrok2 delete share my-gateway From ebd7582a7c4e9cc9154ad2712bf65e9c1aed8810 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:49:49 -0400 Subject: [PATCH 16/21] fixing linter one bucket at a time --- .../openziti/docusaurus/docs/formatting-demo.mdx | 12 ++++++------ .../openziti/docusaurus/docs/formatting-demo2.mdx | 6 +++++- .../versioned_docs/version-beta/formatting-demo.mdx | 12 ++++++------ .../versioned_docs/version-beta/formatting-demo2.mdx | 6 +++++- .../versioned_docs/version-eol/formatting-demo.mdx | 12 ++++++------ .../versioned_docs/version-eol/formatting-demo2.mdx | 6 +++++- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx index d810023..b3c3715 100644 --- a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx +++ b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx @@ -9,6 +9,7 @@ import DetailsExample from './_detail_example.mdx' This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block + ``` @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -28,20 +29,22 @@ A code block inside a bulleted list: drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. -rw-r--r-- 1 user staff 0 Jan 28 12:34 file.txt ``` + :::note this is a note? + ``` and a multiline code comment and a multiline code comment ``` + ::: * this is another bullet - - This here is a "example" block. an example with just results and no matching "language" ends up rendering like a plain code block + ```example @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -51,6 +54,7 @@ drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. This here is a "example" block that has bash attached to it but does not have a command/code section + ```example-bash @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -135,16 +139,12 @@ Regular paragraph here `with a small code chuck` in between. ::: - - - :::caution ::: - ## GitHub Markdown Examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx index 249a9ce..b2f3350 100644 --- a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx +++ b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx @@ -33,6 +33,7 @@ npm run build ## 🧱 Inside Admonition :::note YAML inside a note + ```yaml site: name: MySite @@ -41,6 +42,7 @@ site: - search - analytics ``` + ::: ## πŸ“‹ Lists with Code @@ -48,6 +50,7 @@ site: - Install with `yarn` - Build with `npm run build` - Run a local server: + ```bash npx serve dist ``` @@ -88,7 +91,6 @@ function debounce void>(fn: F, delay = 300): F { } ``` - Demonstrates every admonition, `
`, inline HTML, code blocks, and embedded buttons. --- @@ -177,11 +179,13 @@ type Important = "Very"; ```bash echo "Inside details" ``` + :::note ```bash echo "Inside admonition, inside details" ``` + ::: diff --git a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx index d810023..b3c3715 100644 --- a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx @@ -9,6 +9,7 @@ import DetailsExample from './_detail_example.mdx' This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block + ``` @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -28,20 +29,22 @@ A code block inside a bulleted list: drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. -rw-r--r-- 1 user staff 0 Jan 28 12:34 file.txt ``` + :::note this is a note? + ``` and a multiline code comment and a multiline code comment ``` + ::: * this is another bullet - - This here is a "example" block. an example with just results and no matching "language" ends up rendering like a plain code block + ```example @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -51,6 +54,7 @@ drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. This here is a "example" block that has bash attached to it but does not have a command/code section + ```example-bash @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -135,16 +139,12 @@ Regular paragraph here `with a small code chuck` in between. ::: - - - :::caution ::: - ## GitHub Markdown Examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx b/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx index 249a9ce..b2f3350 100644 --- a/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx +++ b/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx @@ -33,6 +33,7 @@ npm run build ## 🧱 Inside Admonition :::note YAML inside a note + ```yaml site: name: MySite @@ -41,6 +42,7 @@ site: - search - analytics ``` + ::: ## πŸ“‹ Lists with Code @@ -48,6 +50,7 @@ site: - Install with `yarn` - Build with `npm run build` - Run a local server: + ```bash npx serve dist ``` @@ -88,7 +91,6 @@ function debounce void>(fn: F, delay = 300): F { } ``` - Demonstrates every admonition, `
`, inline HTML, code blocks, and embedded buttons. --- @@ -177,11 +179,13 @@ type Important = "Very"; ```bash echo "Inside details" ``` + :::note ```bash echo "Inside admonition, inside details" ``` + ::: diff --git a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx index d810023..b3c3715 100644 --- a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx @@ -9,6 +9,7 @@ import DetailsExample from './_detail_example.mdx' This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block + ``` @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -28,20 +29,22 @@ A code block inside a bulleted list: drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. -rw-r--r-- 1 user staff 0 Jan 28 12:34 file.txt ``` + :::note this is a note? + ``` and a multiline code comment and a multiline code comment ``` + ::: * this is another bullet - - This here is a "example" block. an example with just results and no matching "language" ends up rendering like a plain code block + ```example @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -51,6 +54,7 @@ drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. This here is a "example" block that has bash attached to it but does not have a command/code section + ```example-bash @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . @@ -135,16 +139,12 @@ Regular paragraph here `with a small code chuck` in between. ::: - - - :::caution ::: - ## GitHub Markdown Examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx b/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx index 249a9ce..b2f3350 100644 --- a/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx +++ b/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx @@ -33,6 +33,7 @@ npm run build ## 🧱 Inside Admonition :::note YAML inside a note + ```yaml site: name: MySite @@ -41,6 +42,7 @@ site: - search - analytics ``` + ::: ## πŸ“‹ Lists with Code @@ -48,6 +50,7 @@ site: - Install with `yarn` - Build with `npm run build` - Run a local server: + ```bash npx serve dist ``` @@ -88,7 +91,6 @@ function debounce void>(fn: F, delay = 300): F { } ``` - Demonstrates every admonition, `
`, inline HTML, code blocks, and embedded buttons. --- @@ -177,11 +179,13 @@ type Important = "Very"; ```bash echo "Inside details" ``` + :::note ```bash echo "Inside admonition, inside details" ``` + ::: From 0adb88399f8cc39206eadd5698a03ce55f0e9412 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:59:22 -0400 Subject: [PATCH 17/21] fixing linter one bucket at a time --- .github/workflows/vale-check.yml | 10 +++++---- README.md | 6 ++--- packages/test-site/README.md | 2 +- packages/test-site/docs/code-theme/config.md | 2 +- .../test-site/docs/markdown/code-blocks.mdx | 2 +- packages/test-site/docs/media/images.mdx | 4 ++-- packages/test-site/src/pages/mdtest.mdx | 22 +++++++++---------- skills/doc-check/SKILL.md | 18 +++++++-------- unified-doc/README.md | 8 ++++--- 9 files changed, 39 insertions(+), 35 deletions(-) diff --git a/.github/workflows/vale-check.yml b/.github/workflows/vale-check.yml index 44344cc..b46f6c3 100644 --- a/.github/workflows/vale-check.yml +++ b/.github/workflows/vale-check.yml @@ -12,10 +12,12 @@ jobs: - uses: actions/checkout@v3 - name: Install Tools run: | - # Install Vale - wget https://github.com/errata-ai/vale/releases/download/v3.9.0/vale_3.9.0_Linux_64-bit.tar.gz - tar -xvzf vale_3.9.0_Linux_64-bit.tar.gz - sudo mv vale /usr/local/bin/ + # Install Vale. Extract outside the repo: the tarball ships its own + # README.md/LICENSE, which otherwise clobber ours and get linted. + tmp="$(mktemp -d)" + wget -qO "$tmp/vale.tar.gz" https://github.com/errata-ai/vale/releases/download/v3.9.0/vale_3.9.0_Linux_64-bit.tar.gz + tar -xzf "$tmp/vale.tar.gz" -C "$tmp" vale + sudo mv "$tmp/vale" /usr/local/bin/ # Install Markdownlint npm install -g markdownlint-cli - name: Run Quality Check diff --git a/README.md b/README.md index 80fc4e3..18b1dc3 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Shared documentation theme, components, and tooling for NetFoundry's Docusaurus- ## Repository Structure -``` +```text docusaurus-shared/ β”œβ”€β”€ packages/ β”‚ β”œβ”€β”€ docusaurus-theme/ # @netfoundry/docusaurus-theme npm package @@ -115,7 +115,7 @@ Here [is a link](/docs/to/some/path.md) Add images to the static folder scoped to your site: -``` +```text /your-doc-site/static/img/your-doc-site/ ``` @@ -135,7 +135,7 @@ import SharedContent from '../_shared.content.md' The docusaurus site is hosted on Kinsta. Required nginx rule: -``` +```nginx location /docs/ { try_files $uri $uri/ $uri/index.html /docs/index.html; } diff --git a/packages/test-site/README.md b/packages/test-site/README.md index a1c6392..9bf5b38 100644 --- a/packages/test-site/README.md +++ b/packages/test-site/README.md @@ -93,7 +93,7 @@ resolves correctly. ## Docs organization -``` +```text docs/ β”œβ”€β”€ index.mdx landing page with card grid (slug: /) β”œβ”€β”€ _partials/ underscore-prefixed; ignored by sidebar diff --git a/packages/test-site/docs/code-theme/config.md b/packages/test-site/docs/code-theme/config.md index 758e194..0e73f24 100644 --- a/packages/test-site/docs/code-theme/config.md +++ b/packages/test-site/docs/code-theme/config.md @@ -2,7 +2,7 @@ sidebar_label: "Config (YAML / JSON / Docker)" --- -# Theme test: config formats +# Theme test: Config formats ## YAML diff --git a/packages/test-site/docs/markdown/code-blocks.mdx b/packages/test-site/docs/markdown/code-blocks.mdx index 37120c5..dbb7145 100644 --- a/packages/test-site/docs/markdown/code-blocks.mdx +++ b/packages/test-site/docs/markdown/code-blocks.mdx @@ -41,7 +41,7 @@ function greet(name) { } ``` -## Combined: title, line numbers, and highlighting +## Combined: Title, line numbers, and highlighting ```ts title="src/greet.ts" showLineNumbers {3-4} export function greet(name: string): number { diff --git a/packages/test-site/docs/media/images.mdx b/packages/test-site/docs/media/images.mdx index 8904717..f1cc0be 100644 --- a/packages/test-site/docs/media/images.mdx +++ b/packages/test-site/docs/media/images.mdx @@ -75,5 +75,5 @@ Embedding inside admonitions: | Logo | Description | |-----------------------------------------|-------------------| -| | The brand mark | -| | The brand mark | +| brand mark | The brand mark | +| brand mark | The brand mark | diff --git a/packages/test-site/src/pages/mdtest.mdx b/packages/test-site/src/pages/mdtest.mdx index 72c9f9a..9098f3c 100644 --- a/packages/test-site/src/pages/mdtest.mdx +++ b/packages/test-site/src/pages/mdtest.mdx @@ -1,11 +1,11 @@ ---- -title: Home -description: Minimal Docusaurus page ---- - -# Hello - -This is a basic Docusaurus page. - -- Add content here. -- Markdown and MDX both work. \ No newline at end of file +--- +title: Home +description: Minimal Docusaurus page +--- + +# Hello + +This is a basic Docusaurus page. + +- Add content here. +- Markdown and MDX both work. diff --git a/skills/doc-check/SKILL.md b/skills/doc-check/SKILL.md index 0789381..966743d 100644 --- a/skills/doc-check/SKILL.md +++ b/skills/doc-check/SKILL.md @@ -3,7 +3,7 @@ name: doc-check description: Check merged PRs in a repo for customer-facing changes, cross-reference against existing docs, and flag what is missing, stale, or already covered --- -Check merged PRs in a product's source repo(s) for customer-facing changes. For each flagged PR, search the local doc +Check merged PRs in a product's source repos for customer-facing changes. For each flagged PR, search the local doc directory to assess whether coverage already exists, is stale, or is missing entirely. Produce an actionable report, then optionally generate a doc draft. @@ -17,7 +17,7 @@ Before using this skill, configure it for your organization: ## Invocation -``` +```text /doc-check status /doc-check /doc-check --since YYYY-MM-DD @@ -126,12 +126,12 @@ combined total (most recent first across repos). In the report, prefix each PR w **Monorepos**: If a source repo hosts multiple products, read the PR title, description, and diff to determine which product it belongs to before assessing doc coverage. Mark PRs for other products as skipped with a note. -### 3. Assess each PR: customer-facing or internal? +### 3. Assess each PR: Customer-facing or internal? Fetch the diff for each PR in **two passes**. Never truncate or pipe through `head` β€” silently dropping later parts of a diff means you miss entire files and their changes, which leads to false coverage assessments. -#### Pass 1: get the full file list +#### Pass 1: Get the full file list ```bash # GitHub @@ -151,7 +151,7 @@ This gives you the complete list of changed files before you read any content. U what's left uncovered - Scope the content pass to files that matter -#### Pass 2: read the content of relevant files +#### Pass 2: Read the content of relevant files For each file identified in pass 1 that could affect user-facing behavior, read its diff section in full. For large diffs, use targeted extraction rather than reading the whole diff linearly: @@ -232,7 +232,7 @@ Dismiss **covered** PRs from the flagged list entirely (move them to a "no actio ### 5. Output the report -``` +```markdown ## doc-check: product-a (since 2026-03-18) Sources: your-org/repo-a (6 PRs), your-org/repo-b (4 PRs) β€” 10 total Β· 2 need doc work Β· 1 already covered Β· 7 skipped (internal) @@ -297,7 +297,7 @@ When `--draft ` is passed: Drafts are saved to `output//drafts/` under the doc-check skill folder: -``` +```text /doc-check/output//drafts/--.md ``` @@ -328,7 +328,7 @@ Filename format: `YYYY-MM-DD.md` (use today's date). If a file with that name al Write the report in the same markdown format shown in step 5, with a one-line header added at the top: -``` +```markdown # doc-check: β€” YYYY-MM-DD ``` @@ -336,7 +336,7 @@ Write the report in the same markdown format shown in step 5, with a one-line he After saving the report, regenerate `STATUS.md` at the root of the doc-check skill folder: -``` +```text /doc-check/STATUS.md ``` diff --git a/unified-doc/README.md b/unified-doc/README.md index b2a4411..c8c621c 100644 --- a/unified-doc/README.md +++ b/unified-doc/README.md @@ -59,12 +59,12 @@ Not using SSH: GIT_USER= yarn deploy ``` - ### Kinsta Hosting As of Sep 2025 - the technical docs have been published to the public folder on kinsta. A **CUSTOM** rule was added by tech support: -``` + +```nginx location /docs { try_files $uri /docs/index.html; } @@ -140,6 +140,7 @@ Generated config files (`backstop..json`) include: - **delay: 2000ms** - Waits for page load before screenshot The `onReady.js` script automatically hides: + - Cookie consent banners - Chat widgets - Hotjar feedback widgets @@ -147,6 +148,7 @@ The `onReady.js` script automatically hides: ### Filtering The scenario generator excludes: + - Blog posts (`/blog/`) - zrok versioned docs (only tests latest) - Tag pages @@ -154,7 +156,7 @@ The scenario generator excludes: ### Files -``` +```text unified-doc/ β”œβ”€β”€ scripts/ β”‚ └── generate-vrt-scenarios.mjs # Sitemap parser & config generator From 1b4d0fdad94e20368aea308bc8280326adf07bb9 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:01:58 -0400 Subject: [PATCH 18/21] fixing linter one bucket at a time --- .../remotes/openziti/docusaurus/docs/formatting-demo.mdx | 6 +++--- .../test-site/remotes/zrok/website/docs/formatting-demo.mdx | 2 +- .../versioned_docs/version-beta/formatting-demo.mdx | 6 +++--- .../versioned_docs/version-eol/formatting-demo.mdx | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx index b3c3715..e4bb8d3 100644 --- a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx +++ b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx @@ -10,7 +10,7 @@ This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block -``` +```text @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. @@ -21,7 +21,7 @@ A code block inside a bulleted list: * this is the bullet text - ``` + ```text this is text this is text this is text @@ -33,7 +33,7 @@ A code block inside a bulleted list: :::note this is a note? - ``` + ```text and a multiline code comment and a multiline code comment ``` diff --git a/packages/test-site/remotes/zrok/website/docs/formatting-demo.mdx b/packages/test-site/remotes/zrok/website/docs/formatting-demo.mdx index 24a63e8..0722d6a 100644 --- a/packages/test-site/remotes/zrok/website/docs/formatting-demo.mdx +++ b/packages/test-site/remotes/zrok/website/docs/formatting-demo.mdx @@ -6,7 +6,7 @@ title: zrok formatting demo This is `what` a `regular` code block `that is inline` will look like. -``` +```text @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. diff --git a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx index b3c3715..e4bb8d3 100644 --- a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx @@ -10,7 +10,7 @@ This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block -``` +```text @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. @@ -21,7 +21,7 @@ A code block inside a bulleted list: * this is the bullet text - ``` + ```text this is text this is text this is text @@ -33,7 +33,7 @@ A code block inside a bulleted list: :::note this is a note? - ``` + ```text and a multiline code comment and a multiline code comment ``` diff --git a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx index b3c3715..e4bb8d3 100644 --- a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx @@ -10,7 +10,7 @@ This is `what` a `regular` code block `that is inline` will look like. This here is a "plain" code block -``` +```text @results: total 12 drwxr-xr-x 5 user staff 160 Jan 28 12:34 . drwxr-xr-x 20 user staff 640 Jan 28 12:34 .. @@ -21,7 +21,7 @@ A code block inside a bulleted list: * this is the bullet text - ``` + ```text this is text this is text this is text @@ -33,7 +33,7 @@ A code block inside a bulleted list: :::note this is a note? - ``` + ```text and a multiline code comment and a multiline code comment ``` From 5ff6aaf126d04e735d9459a67598dece4ef84e80 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:07:44 -0400 Subject: [PATCH 19/21] fixing linter one bucket at a time --- .../config/vocabularies/terms/accept.txt | 66 ++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/docs-linter/styles/config/vocabularies/terms/accept.txt b/docs-linter/styles/config/vocabularies/terms/accept.txt index 18ce1df..dd5eecb 100644 --- a/docs-linter/styles/config/vocabularies/terms/accept.txt +++ b/docs-linter/styles/config/vocabularies/terms/accept.txt @@ -2,6 +2,17 @@ (?i)config (?i)ip (?i)hostname +(?i)docusaurus +(?i)failover +(?i)failovers +(?i)markdown +(?i)h1 +(?i)h2 +(?i)h3 +(?i)h4 +(?i)h5 +(?i)h6 +(?i)test-site # URLs and domains openziti.io @@ -16,8 +27,6 @@ datacenter datacenters egress egressed -failover -failovers ingress ingressed microsegmentation @@ -29,42 +38,93 @@ untrusted # Documentation-specific terms sidebar_position sidebar_label +showLineNumbers +STATUS.md + +# Theme components and remark plugins (rendered verbatim in headings) +MarkdownWithoutH1 +OsTabs +ProductSearch +StarUs +remarkReplaceMetaUrl +remarkScopedPath +remarkYamlTable +remarkYouTube # Product/Brand names -Docusaurus Frontdoor +LLM Gateway +MCP Gateway NetFoundry +NetFoundry Docusaurus Shared +On-Prem OpenZiti Ziti zLAN zrok +# Binaries and CLI tool names (lowercase by design) +curl +llm-gateway +mcp-bridge +mcp-gateway +mcp-tools + # Third-party products/services +Beta Bitbucket +Claude +Claude Desktop +ECharts GitHub JavaScript +KaTeX Keycloak +Kinsta Kubernetes +Mermaid Okta +Ollama +Scalar +Stable TypeScript # Acronyms and initialisms +Active LTS AMI AMIs API CA CAs CLI +CSS +EOL FQDN FQDNs +Go +HTML +HTTP IdP IdPs +JSON +JSX JWT JWTs +LLM +LTS +MCP +MDX MFA +OpenAPI +PR +PRs +TL;DR TLDs +URL +URLs VM VMs +YAML # Other terms namespace From e920f1ccf7cdb34f9ae7fcf461e716a25fd49df5 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:13:44 -0400 Subject: [PATCH 20/21] fixing linter one bucket at a time --- README.md | 16 ++++++++-------- .../styles/config/vocabularies/terms/accept.txt | 2 ++ nf-style-guide.md | 4 ++-- packages/test-site/README.md | 2 +- packages/test-site/docs/markdown/typography.mdx | 12 ++++++------ .../remotes/onprem/docusaurus/docs/index.mdx | 2 +- .../openziti/docusaurus/docs/formatting-demo.mdx | 4 ++-- .../docusaurus/docs/formatting-demo2.mdx | 14 +++++++------- .../version-beta/formatting-demo.mdx | 4 ++-- .../version-beta/formatting-demo2.mdx | 14 +++++++------- .../version-eol/formatting-demo.mdx | 4 ++-- .../version-eol/formatting-demo2.mdx | 14 +++++++------- skills/doc-check/SKILL.md | 4 ++-- unified-doc/README.md | 10 +++++----- unified-doc/docs/intro.md | 2 +- 15 files changed, 55 insertions(+), 53 deletions(-) diff --git a/README.md b/README.md index 18b1dc3..86cc533 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Shared documentation theme, components, and tooling for NetFoundry's Docusaurus-based documentation sites. -## Repository Structure +## Repository structure ```text docusaurus-shared/ @@ -17,9 +17,9 @@ docusaurus-shared/ See [`packages/test-site/README.md`](./packages/test-site/README.md) for the test-site dev loop, docs organization, and debug recipes. -## Quick Start +## Quick start -### Using the Theme +### Using the theme Install the theme in your Docusaurus project: @@ -52,7 +52,7 @@ export default { See the [theme README](./packages/docusaurus-theme/README.md) for full documentation. -### Creating a New Doc Site +### Creating a new doc site ```bash ./bootstrap.sh /path/to/new-site [starLabel] [starRepoUrl] @@ -88,7 +88,7 @@ See [packages/test-site/README.md](./packages/test-site/README.md) for the full dev-loop walkthrough, debug recipes, and what hot-reloads vs. what needs a rebuild. -## Local Development +## Local development See [packages/LOCAL-DEV.md](./packages/LOCAL-DEV.md) for the full local development guide, including how to use the test-site, test with remote sites via `file:` protocol, and publish. @@ -96,9 +96,9 @@ See [packages/LOCAL-DEV.md](./packages/LOCAL-DEV.md) for the full local developm See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, workflow, and a walkthrough example of making theme changes. -## Best Practices +## Best practices -### Relative Linking +### Relative linking Use relative paths for internal links: @@ -131,7 +131,7 @@ import SharedContent from '../_shared.content.md' ``` -## Kinsta Hosting +## Kinsta hosting The docusaurus site is hosted on Kinsta. Required nginx rule: diff --git a/docs-linter/styles/config/vocabularies/terms/accept.txt b/docs-linter/styles/config/vocabularies/terms/accept.txt index dd5eecb..c642160 100644 --- a/docs-linter/styles/config/vocabularies/terms/accept.txt +++ b/docs-linter/styles/config/vocabularies/terms/accept.txt @@ -13,6 +13,8 @@ (?i)h5 (?i)h6 (?i)test-site +(?i)code +(?i)vs # URLs and domains openziti.io diff --git a/nf-style-guide.md b/nf-style-guide.md index aef5cf7..1703aab 100644 --- a/nf-style-guide.md +++ b/nf-style-guide.md @@ -73,7 +73,7 @@ We use a DiΓ‘taxis framework. When creating content, think in terms of these fou - **Tutorials** (Learning-oriented) - **Goal:** To help the user *learn* by doing. - - **Description:** Step-by-step lessons that allow the user to successfully complete a practical, simple project. They + - **Description:** Step-by-step lessons that allow the user to complete a practical, simple project. They are focused on **teaching**, not explaining, and prioritize the shortest path to success. - **Question answered:** *How do I get started?* @@ -123,7 +123,7 @@ The exact top-level buckets we use for the ToC can vary depending on the product - Don't use "the button". Say "Click **Next**." - Tell the user to *click* UI items. If it's a drop-down, use *select*. -## Images and File Names +## Images and file names - A significant amount of readers are on mobile. Don't use images wider than 600-700 px. Shrink browsers for screenshots. diff --git a/packages/test-site/README.md b/packages/test-site/README.md index 9bf5b38..4acdc70 100644 --- a/packages/test-site/README.md +++ b/packages/test-site/README.md @@ -205,7 +205,7 @@ yarn workspace test-site serve # serve the built output locally The static output lands in `packages/test-site/build/`. Useful for verifying that a change works in a real production bundle, not just dev mode. -## When to put something HERE vs. somewhere else +## When to put something here vs. somewhere else | Goal | Goes in | |-----------------------------------------------|--------------------------------------------------------| diff --git a/packages/test-site/docs/markdown/typography.mdx b/packages/test-site/docs/markdown/typography.mdx index c7b756d..6dac127 100644 --- a/packages/test-site/docs/markdown/typography.mdx +++ b/packages/test-site/docs/markdown/typography.mdx @@ -7,17 +7,17 @@ regressions in `legacy.css` or the IFM defaults. ## Heading levels -# h1 -- The largest heading +# h1 -- the largest heading -## h2 -- A major section +## h2 -- a major section -### h3 -- A subsection +### h3 -- a subsection -#### h4 -- A sub-subsection +#### h4 -- a sub-subsection -##### h5 -- Rarely used +##### h5 -- rarely used -###### h6 -- The smallest heading +###### h6 -- the smallest heading ## Paragraphs and inline marks diff --git a/packages/test-site/remotes/onprem/docusaurus/docs/index.mdx b/packages/test-site/remotes/onprem/docusaurus/docs/index.mdx index 87dc752..25d7a88 100644 --- a/packages/test-site/remotes/onprem/docusaurus/docs/index.mdx +++ b/packages/test-site/remotes/onprem/docusaurus/docs/index.mdx @@ -1,4 +1,4 @@ -# Self-Hosted (On-Prem) +# Self-hosted (On-Prem) Welcome to the NetFoundry Self-Hosted documentation. diff --git a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx index e4bb8d3..81396b9 100644 --- a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx +++ b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo.mdx @@ -101,7 +101,7 @@ echo "Hello, World!" # Bash regular, text here ``` -Regular paragraph here `with a small code chuck` in between. +Regular paragraph here `with a small code chuck` between the fences. :::note @@ -145,7 +145,7 @@ Regular paragraph here `with a small code chuck` in between. ::: -## GitHub Markdown Examples +## GitHub Markdown examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx index b2f3350..1b1ee11 100644 --- a/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx +++ b/packages/test-site/remotes/openziti/docusaurus/docs/formatting-demo2.mdx @@ -30,7 +30,7 @@ npm run build } ``` -## 🧱 Inside Admonition +## 🧱 Inside admonition :::note YAML inside a note @@ -55,7 +55,7 @@ site: npx serve dist ``` -## 🧩 Mixed Content +## 🧩 Mixed content > ❗ Run `./deploy.sh` only from the `main` branch. > @@ -63,7 +63,7 @@ site: > ./deploy.sh --prod > ``` -## πŸ”— Code inside Table +## πŸ”— Code inside table | Command | Description | |---------|---------------------| @@ -79,7 +79,7 @@ Use raw HTML for buttons: ``` -## 🧬 Complex Function +## 🧬 Complex function ```ts function debounce void>(fn: F, delay = 300): F { @@ -169,7 +169,7 @@ type Important = "Very"; --- -## πŸ” Expandable Content +## πŸ” Expandable content
Click to expand @@ -194,7 +194,7 @@ echo "Inside admonition, inside details" --- -## βœ… Confirmed Features +## βœ… Confirmed features - [x] Admonitions - [x] Code blocks @@ -214,7 +214,7 @@ import SomeMd from '/docs/remotes/some-remote/README.md'; See GitHub Markdown admonition examples in the [Code Block Formatting Demo](./formatting-demo.mdx#github-markdown-examples) -### When to Use the MarkdownWithoutH1 Component with Imported Markdown +### When to use the MarkdownWithoutH1 component with imported Markdown When importing GitHub Markdown as MDX, you have two choices for the H1 page title: use the title from the imported Markdown or set an alternative title. diff --git a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx index e4bb8d3..81396b9 100644 --- a/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-beta/formatting-demo.mdx @@ -101,7 +101,7 @@ echo "Hello, World!" # Bash regular, text here ``` -Regular paragraph here `with a small code chuck` in between. +Regular paragraph here `with a small code chuck` between the fences. :::note @@ -145,7 +145,7 @@ Regular paragraph here `with a small code chuck` in between. ::: -## GitHub Markdown Examples +## GitHub Markdown examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx b/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx index b2f3350..1b1ee11 100644 --- a/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx +++ b/packages/test-site/versioned_docs/version-beta/formatting-demo2.mdx @@ -30,7 +30,7 @@ npm run build } ``` -## 🧱 Inside Admonition +## 🧱 Inside admonition :::note YAML inside a note @@ -55,7 +55,7 @@ site: npx serve dist ``` -## 🧩 Mixed Content +## 🧩 Mixed content > ❗ Run `./deploy.sh` only from the `main` branch. > @@ -63,7 +63,7 @@ site: > ./deploy.sh --prod > ``` -## πŸ”— Code inside Table +## πŸ”— Code inside table | Command | Description | |---------|---------------------| @@ -79,7 +79,7 @@ Use raw HTML for buttons: ``` -## 🧬 Complex Function +## 🧬 Complex function ```ts function debounce void>(fn: F, delay = 300): F { @@ -169,7 +169,7 @@ type Important = "Very"; --- -## πŸ” Expandable Content +## πŸ” Expandable content
Click to expand @@ -194,7 +194,7 @@ echo "Inside admonition, inside details" --- -## βœ… Confirmed Features +## βœ… Confirmed features - [x] Admonitions - [x] Code blocks @@ -214,7 +214,7 @@ import SomeMd from '/docs/remotes/some-remote/README.md'; See GitHub Markdown admonition examples in the [Code Block Formatting Demo](./formatting-demo.mdx#github-markdown-examples) -### When to Use the MarkdownWithoutH1 Component with Imported Markdown +### When to use the MarkdownWithoutH1 component with imported Markdown When importing GitHub Markdown as MDX, you have two choices for the H1 page title: use the title from the imported Markdown or set an alternative title. diff --git a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx index e4bb8d3..81396b9 100644 --- a/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx +++ b/packages/test-site/versioned_docs/version-eol/formatting-demo.mdx @@ -101,7 +101,7 @@ echo "Hello, World!" # Bash regular, text here ``` -Regular paragraph here `with a small code chuck` in between. +Regular paragraph here `with a small code chuck` between the fences. :::note @@ -145,7 +145,7 @@ Regular paragraph here `with a small code chuck` in between. ::: -## GitHub Markdown Examples +## GitHub Markdown examples A ReMark plugin translates imported GitHub admonitions to Docusaurus admonitions. Read more about [importing GitHub Markdown](/formatting-demo2.mdx#import-github-markdown). diff --git a/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx b/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx index b2f3350..1b1ee11 100644 --- a/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx +++ b/packages/test-site/versioned_docs/version-eol/formatting-demo2.mdx @@ -30,7 +30,7 @@ npm run build } ``` -## 🧱 Inside Admonition +## 🧱 Inside admonition :::note YAML inside a note @@ -55,7 +55,7 @@ site: npx serve dist ``` -## 🧩 Mixed Content +## 🧩 Mixed content > ❗ Run `./deploy.sh` only from the `main` branch. > @@ -63,7 +63,7 @@ site: > ./deploy.sh --prod > ``` -## πŸ”— Code inside Table +## πŸ”— Code inside table | Command | Description | |---------|---------------------| @@ -79,7 +79,7 @@ Use raw HTML for buttons: ``` -## 🧬 Complex Function +## 🧬 Complex function ```ts function debounce void>(fn: F, delay = 300): F { @@ -169,7 +169,7 @@ type Important = "Very"; --- -## πŸ” Expandable Content +## πŸ” Expandable content
Click to expand @@ -194,7 +194,7 @@ echo "Inside admonition, inside details" --- -## βœ… Confirmed Features +## βœ… Confirmed features - [x] Admonitions - [x] Code blocks @@ -214,7 +214,7 @@ import SomeMd from '/docs/remotes/some-remote/README.md'; See GitHub Markdown admonition examples in the [Code Block Formatting Demo](./formatting-demo.mdx#github-markdown-examples) -### When to Use the MarkdownWithoutH1 Component with Imported Markdown +### When to use the MarkdownWithoutH1 component with imported Markdown When importing GitHub Markdown as MDX, you have two choices for the H1 page title: use the title from the imported Markdown or set an alternative title. diff --git a/skills/doc-check/SKILL.md b/skills/doc-check/SKILL.md index 966743d..9d8a0e3 100644 --- a/skills/doc-check/SKILL.md +++ b/skills/doc-check/SKILL.md @@ -178,7 +178,7 @@ descriptions; the diff is the authoritative source. Look for: Also read any doc files the author changed in the PR β€” understand what they covered so your coverage assessment reflects what's actually missing, not what was already addressed. -**Bitbucket note:** The simple `/pullrequests//diff` endpoint returns empty results. Batch-extract commit +**Bitbucket note:** The simple `/pullrequests//diff` endpoint returns empty results. Batch-fetch commit hashes from the PR list response (fields `source.commit.hash` and `destination.commit.hash`) and construct the diff URL as shown above. @@ -213,7 +213,7 @@ current local state β€” don't abort the scan. For each customer-facing PR, search the local doc path for the product (see registry above) to determine whether coverage already exists. Use grep and file reads β€” do not guess. -Extract 2–4 key terms from the PR (feature name, CLI flag, config key, endpoint name, etc.) and search for them: +Identify 2–4 key terms from the PR (feature name, CLI flag, config key, endpoint name, etc.) and search for them: ```bash grep -r "" --include="*.md" --include="*.mdx" -l diff --git a/unified-doc/README.md b/unified-doc/README.md index c8c621c..304e5d4 100644 --- a/unified-doc/README.md +++ b/unified-doc/README.md @@ -8,7 +8,7 @@ This website is built using [Docusaurus](https://docusaurus.io/), a modern stati yarn ``` -## Local Development +## Local development ```bash yarn start @@ -59,7 +59,7 @@ Not using SSH: GIT_USER= yarn deploy ``` -### Kinsta Hosting +### Kinsta hosting As of Sep 2025 - the technical docs have been published to the public folder on kinsta. A **CUSTOM** rule was added by tech support: @@ -74,7 +74,7 @@ This rule is **mandatory** for SPA deep linking. The tech support people had to --- -## Visual Regression Testing +## Visual regression testing The unified-doc site includes BackstopJS for visual regression testing against production. This helps catch unintended visual changes when updating the theme, components, or content. @@ -85,7 +85,7 @@ The unified-doc site includes BackstopJS for visual regression testing against p - 3 viewports: desktop (1920x1080), tablet (768x1024), mobile (375x812) - Generates HTML diff reports highlighting visual differences -### Quick Start +### Quick start ```bash # Install dependencies (includes backstopjs) @@ -108,7 +108,7 @@ yarn vrt:test:zlan yarn vrt:report:zlan ``` -### Available Commands +### Available commands Each product has its own set of commands: diff --git a/unified-doc/docs/intro.md b/unified-doc/docs/intro.md index a3be402..a295eda 100644 --- a/unified-doc/docs/intro.md +++ b/unified-doc/docs/intro.md @@ -2,4 +2,4 @@ sidebar_position: 1 --- -# Empty Page +# Empty page From c6030eeeee5606889c28421cd2185018711f7443 Mon Sep 17 00:00:00 2001 From: dovholuknf <46322585+dovholuknf@users.noreply.github.com> Date: Fri, 24 Jul 2026 14:16:40 -0400 Subject: [PATCH 21/21] fixing linter one bucket at a time --- .github/workflows/vale-check.yml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/vale-check.yml b/.github/workflows/vale-check.yml index b46f6c3..09f6295 100644 --- a/.github/workflows/vale-check.yml +++ b/.github/workflows/vale-check.yml @@ -11,15 +11,22 @@ jobs: steps: - uses: actions/checkout@v3 - name: Install Tools + env: + # Keep in step with the version developers run locally -- older Vale + # reports Microsoft.Headings false positives this repo can't reproduce. + VALE_VERSION: 3.15.2 run: | # Install Vale. Extract outside the repo: the tarball ships its own # README.md/LICENSE, which otherwise clobber ours and get linted. tmp="$(mktemp -d)" - wget -qO "$tmp/vale.tar.gz" https://github.com/errata-ai/vale/releases/download/v3.9.0/vale_3.9.0_Linux_64-bit.tar.gz + wget -qO "$tmp/vale.tar.gz" \ + "https://github.com/errata-ai/vale/releases/download/v${VALE_VERSION}/vale_${VALE_VERSION}_Linux_64-bit.tar.gz" tar -xzf "$tmp/vale.tar.gz" -C "$tmp" vale sudo mv "$tmp/vale" /usr/local/bin/ + vale -v # Install Markdownlint npm install -g markdownlint-cli + markdownlint --version - name: Run Quality Check run: | chmod +x docs-linter/lint.sh