@f5-sales-demo/xcsh 22.2.0 → 22.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,17 +17,17 @@ export interface BuildInfo {
17
17
  }
18
18
 
19
19
  export const BUILD_INFO: BuildInfo = {
20
- "version": "22.2.0",
21
- "commit": "5d9f4f3ce9b3fc191846cfe6fa37d60afab62421",
22
- "shortCommit": "5d9f4f3",
20
+ "version": "22.3.1",
21
+ "commit": "978281d4e8d54aa7f114e6925cdcdae2837504ce",
22
+ "shortCommit": "978281d",
23
23
  "branch": "main",
24
- "tag": "v22.2.0",
25
- "commitDate": "2026-09-28T01:49:00Z",
26
- "buildDate": "2026-09-28T02:25:11.763Z",
24
+ "tag": "v22.3.1",
25
+ "commitDate": "2026-09-28T05:26:47Z",
26
+ "buildDate": "2026-09-28T06:09:14.324Z",
27
27
  "dirty": true,
28
28
  "prNumber": "",
29
29
  "repoUrl": "https://github.com/f5-sales-demo/xcsh",
30
30
  "repoSlug": "f5-sales-demo/xcsh",
31
- "commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/5d9f4f3ce9b3fc191846cfe6fa37d60afab62421",
32
- "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v22.2.0"
31
+ "commitUrl": "https://github.com/f5-sales-demo/xcsh/commit/978281d4e8d54aa7f114e6925cdcdae2837504ce",
32
+ "releaseUrl": "https://github.com/f5-sales-demo/xcsh/releases/tag/v22.3.1"
33
33
  };
@@ -40,14 +40,14 @@ export const EMBEDDED_DOCS: Readonly<Record<string, string>> = {
40
40
  "en/getting-started/first-manifest.mdx": "---\ntitle: \"Complete your first manifest lifecycle\"\ndescription: \"Validate, compare, apply, inspect, export, and delete one resource manifest.\"\nsidebar:\n order: 5\n label: \"First manifest\"\nhead:\n - tag: style\n content: |\n .sl-markdown-content .expressive-code { max-width: 100%; overflow-x: auto; }\n .sl-markdown-content table { display: block; max-width: 100%; overflow-x: auto; }\n---\n\nA manifest names one F5 Distributed Cloud resource with `kind`, `metadata`, and `spec`. Begin from an exported or catalog-backed example for the exact resource kind; do not invent schema fields. This page walks one resource from local validation to proven deletion, so run it against a lab namespace you are authorized to change.\n\n## How do I check a manifest without credentials?\n\n```bash\nxcsh validate -f manifest.yaml --result-file validation.json\n```\n\nValidation reads the file locally and returns a nonzero status for malformed or unsupported input. Review the aggregate JavaScript Object Notation (JSON) report before moving to a live context.\n\n## How do I preview the live change?\n\n```bash\nxcsh diff -f manifest.yaml --result-file diff.json\nxcsh apply -f manifest.yaml --dry-run client --result-file dry-run.json\n```\n\nA diff requires the intended context. A dry run calculates the mutation path without applying it. Read every create, update, and preserve entry before you continue.\n\n## How do I apply and verify the resource?\n\n```bash\nxcsh apply -f manifest.yaml --result-file apply.json\nxcsh get <KIND> <NAME> -n <NAMESPACE> --result-file get.json\n```\n\nCompare the identity and the fields you set in `get.json` against the manifest. A zero exit status records that the request was accepted; only the retrieved object records the resulting state.\n\n## How do I export and remove it?\n\n```bash\nxcsh export <KIND> <NAME> -n <NAMESPACE> -f exported.yaml\nxcsh delete <KIND> <NAME> -n <NAMESPACE> --result-file delete.json\nxcsh get <KIND> <NAME> -n <NAMESPACE>\n```\n\nSanitize server-managed metadata out of `exported.yaml` before you store it. The closing `get` must return the not-found response for that kind; a delete request without the absence check leaves the lifecycle unfinished.\n",
41
41
  "en/getting-started/index.mdx": "---\ntitle: \"Getting started\"\ndescription: \"Install xcsh, connect a model and an F5 Distributed Cloud tenant, and complete a safe first workflow.\"\nsidebar:\n order: 0\n label: \"Overview\"\n---\n\nUse this section to reach the first useful command without configuring every optional integration.\n\n## What do I need before I begin?\n\nYou need a supported xcsh build and one model provider. F5 Distributed Cloud credentials are needed only for live resource commands; local manifest validation works without them.\n\n## Which path matches my goal?\n\n1. [Install, update, or remove xcsh](/xcsh/en/#install-xcsh).\n2. [Authenticate a model](/xcsh/en/getting-started/model-authentication/), which the quickstart requires.\n3. Run the [general quickstart](/xcsh/en/#quickstart).\n4. Connect an [F5 Distributed Cloud context](/xcsh/en/f5-distributed-cloud/contexts-namespaces/) when you intend to reach a tenant.\n5. Complete [your first manifest lifecycle](/xcsh/en/getting-started/first-manifest/) against a lab namespace you are authorized to change.\n",
42
42
  "en/getting-started/model-authentication.mdx": "---\ntitle: \"Authenticate a model provider\"\ndescription: \"Configure an API key or supported subscription login without placing credentials in project files.\"\nsidebar:\n order: 2\n label: \"Model authentication\"\nhead:\n - tag: style\n content: |\n .sl-markdown-content .expressive-code { max-width: 100%; overflow-x: auto; }\n .sl-markdown-content table { display: block; max-width: 100%; overflow-x: auto; }\n---\n\nModel credentials belong in the provider-supported environment or subscription login, not in prompts, settings committed to a repository, or command arguments.\n\n## Which authentication method should I choose?\n\nUse a provider application programming interface (API) key for service-style automation. Use a supported subscription login for an interactive user session. Run `xcsh --list-models <PROVIDER>` after authentication to confirm the credential can enumerate models.\n\n## How do I select a model explicitly?\n\n```bash\nxcsh --model p-openai/gpt-5.2 --no-tools -p \"Summarize README.md\"\n```\n\nReplace the example with a model shown by your installed build. Provider-qualified names avoid an accidental fuzzy match when several providers expose similar model names.\n\nFor Anthropic, either complete `/login anthropic` with a Claude subscription or export\n`ANTHROPIC_API_KEY` for direct API billing. `--model fable` and `--model anthropic/fable` are exact\naliases for `anthropic/claude-fable-5-1`; use `anthropic/claude-fable-5` when you specifically need\nthe earlier Fable 5 model. Fable access depends on the selected account's entitlement.\n\nStart xcsh, enter `/login`, and choose only the provider you intend to use. Complete the\nprovider-owned sign-in flow, return to the model picker, and select an explicit model.\nAuthentication may store a refresh token or subscription session outside the repository; a prompt\nnever needs the credential value. Send a no-tool prompt, inspect the selected provider and model,\nthen use `/logout` when the account must not remain available on that workstation.\n",
43
- "en/index.mdx": "---\ntitle: xcsh\ndescription: Install xcsh, authenticate a model provider, and begin a reviewable terminal or F5 Distributed Cloud workflow.\ntemplate: splash\neditUrl: false\nsidebar:\n hidden: true\n order: 0\nhead:\n - tag: style\n content: |\n main:has(.landing-hero) > .content-panel:first-of-type { padding-block-end: .5rem; }\n main:has(.landing-hero) > .content-panel:first-of-type + .content-panel { border-top: 0; padding-block-start: 0; }\n .landing-hero { display: grid; gap: clamp(2rem, 4vw, 4rem); grid-template-columns: minmax(0, 1fr) minmax(18rem, 35rem); align-items: center; margin-block: .75rem 2rem; }\n .landing-hero__content, .landing-hero__image, .landing-installer, .landing-installer .expressive-code, .landing-command { min-width: 0; }\n h1#_top { max-width: 13ch; margin-block-end: 0; text-wrap: balance; }\n .landing-hero__lede { max-width: 42rem; color: var(--sl-color-gray-2); font-size: var(--sl-text-lg); }\n .landing-installer { margin-block: 0 4rem; padding: clamp(1rem, 2vw, 1.5rem); border: 1px solid var(--sl-color-gray-5); border-radius: .75rem; background: var(--sl-color-bg-nav); }\n .landing-installer h2 { margin: 0; font-size: var(--sl-text-lg); }\n .landing-installer p { margin-block: .5rem 0; }\n .landing-installer pre { max-width: 100%; overflow-x: auto; }\n .landing-installer .expressive-code .ec-line .code { padding-inline-end: 3.5rem; white-space: pre; overflow-wrap: normal; }\n .landing-installer .expressive-code .copy button { opacity: 1; }\n .landing-hero__image { margin: 0; }\n .landing-hero__image img { display: block; width: 100%; height: auto; aspect-ratio: 1442 / 1268; object-fit: contain; filter: drop-shadow(0 1rem 2.5rem color-mix(in srgb, var(--sl-color-accent) 28%, transparent)); }\n .landing-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-block: 1.5rem; }\n .landing-explore { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n details.landing-disclosure { margin-block: 1rem 0; padding: .75rem 1rem; border: 1px solid var(--sl-color-gray-5); border-radius: .5rem; background: var(--sl-color-bg-nav); }\n details.landing-disclosure summary { cursor: pointer; font-weight: 600; }\n :is(.landing-hero, .landing-installer, .landing-grid, .landing-disclosure) :is(a, button, summary):focus-visible { outline: 2px solid var(--sl-color-accent-high); outline-offset: 3px; }\n @media (max-width: 50rem) { .landing-hero { grid-template-columns: minmax(0, 1fr); gap: 2rem; margin-block: .5rem 2rem; } .landing-installer { margin-block-end: 3rem; padding: 1rem; } .landing-grid { grid-template-columns: minmax(0, 1fr); } }\n---\n\nimport { Aside, Card, LinkCard, TabItem, Tabs } from '@astrojs/starlight/components';\n\n<section class=\"landing-hero\" aria-labelledby=\"_top\">\n <div class=\"landing-hero__content\">\n <p class=\"landing-hero__lede\">An AI-native terminal assistant for engineering, automation, and reviewable F5 Distributed Cloud workflows.</p>\n <p>xcsh is an independent open-source project derived from pi/pi-mono, specialized for F5 Distributed Cloud workflows; it is not an F5 product.</p>\n </div>\n\n <figure class=\"landing-hero__image\">\n <img src=\"/xcsh/images/xcsh-ghostty-terminal.png\" width=\"1442\" height=\"1268\" alt=\"xcsh running in a Ghostty terminal with the model selector, prompt, and session status visible.\" />\n </figure>\n</section>\n\n<section class=\"landing-installer\" aria-labelledby=\"install-xcsh\">\n\n## Install xcsh\n\n <p>Universal installer for macOS and Linux.</p>\n\n ```bash\n curl -fsSL https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.sh | sh\n ```\n\n <p>It installs the latest prebuilt release into <code>~/.local/bin</code> with a provenance receipt. This is the only channel that <code>xcsh self-update</code> replaces in process. Need a managed or platform-specific channel? Compare the <a href=\"#installation-options\">installation options</a>.</p>\n</section>\n\n## What xcsh helps you do\n\n<div class=\"landing-grid landing-capabilities\">\n <Card title=\"Agentic terminal work\" icon=\"terminal\">\n Run interactive or print-mode prompts, inspect files, use tools, and keep durable session history when the task needs it. [Learn the agent loop](/xcsh/en/use-xcsh/agent-loop/).\n </Card>\n <Card title=\"Reviewable F5 Distributed Cloud workflows\" icon=\"document\">\n Discover schemas, validate manifests, and inspect proposed differences before an authorized resource change. [Use resource workflows](/xcsh/en/f5-distributed-cloud/).\n </Card>\n <Card title=\"Extensible automation\" icon=\"puzzle\">\n Add headless workflows, custom tools, skills, or plugins when built-in commands are not enough. [Automate and extend](/xcsh/en/automate-extend/).\n </Card>\n</div>\nThese workflows start with a working executable; choose another channel only when the universal installer is not the right fit.\n\n## Installation options\n\nUse one channel for install and upgrades. Mixing package-manager and standalone installations can leave more than one `xcsh` on `PATH`; the universal installer above is not repeated here.\n\n<Tabs syncKey=\"install-platform\">\n<TabItem label=\"macOS\" icon=\"seti:apple\">\nInstall the signed and notarized macOS archive through the Homebrew cask. The cask preserves the released executable and native addon byte for byte and does not require `sudo`:\n\n```bash\nbrew install --cask f5-sales-demo/tap/xcsh\n```\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `brew upgrade --cask f5-sales-demo/tap/xcsh`. Remove the cask with `brew uninstall --cask xcsh`. `xcsh self-update` reports the tap-qualified command but never invokes Homebrew. These commands preserve configuration, credentials, and sessions under `~/.xcsh`.\n</details>\n\n<Aside type=\"caution\" title=\"Clean break from the historical package cask\">\nBefore installing this cask on a Mac that received an earlier xcsh package,\nuninstall both old Homebrew entries (`brew uninstall --formula xcsh` and\n`brew uninstall --cask xcsh`). Then have MDM forget the `com.f5.xcsh` receipt\nand remove only the package-owned `/usr/local/bin/xcsh` and\n`/Library/Application Support/xcsh` payload. Do not remove `~/.xcsh`. The signed\nand stapled `.pkg` release assets remain available only for direct MDM\ndeployment.\n</Aside>\n</TabItem>\n\n<TabItem label=\"Ubuntu or Debian\" icon=\"seti:ubuntu\">\nThe signed apt repository supports amd64 and arm64 and follows normal system upgrades:\n\n```bash\nsudo install -d -m 0755 /etc/apt/keyrings\ncurl -fsSL https://f5-sales-demo.github.io/apt-repo/f5xc-archive-keyring.gpg \\\n | sudo tee /etc/apt/keyrings/f5xc-archive-keyring.gpg >/dev/null\necho \"deb [arch=amd64,arm64 signed-by=/etc/apt/keyrings/f5xc-archive-keyring.gpg] https://f5-sales-demo.github.io/apt-repo stable main\" \\\n | sudo tee /etc/apt/sources.list.d/f5xc.list\nsudo apt-get update && sudo apt-get install xcsh\n```\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `sudo apt-get update && sudo apt-get install --only-upgrade xcsh`. Remove the package with `sudo apt-get remove xcsh`. `xcsh self-update` reports this command when `dpkg-query` proves that package `xcsh` owns the running executable; it never invokes apt.\n</details>\n</TabItem>\n\n<TabItem label=\"Windows\" icon=\"seti:windows\">\nRun the PowerShell installer, then restart the terminal so its user `PATH` refreshes:\n\n```powershell\nirm https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.ps1 | iex\n```\n\nIt installs `xcsh.exe` and native add-ons to `%LOCALAPPDATA%\\\\xcsh`. **Bash is required for tool-backed sessions.** Install Git for Windows, WSL, Cygwin, or MSYS2; set `shellPath` in `%USERPROFILE%\\\\.xcsh\\\\agent\\\\settings.json` when Bash is elsewhere.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nRe-run the installer to upgrade. `xcsh self-update` reports the PowerShell installer command but does not replace a Windows installer-owned executable. To uninstall, remove `%LOCALAPPDATA%\\\\xcsh` and its entry from the user `PATH`.\n</details>\n</TabItem>\n\n<TabItem label=\"Container\" icon=\"seti:docker\">\nDocker and Podman use the same multi-architecture image. Pin a release tag, resolve its digest for deployment, and mount only the workspace and state required by the task:\n\n```bash\ndocker pull ghcr.io/f5-sales-demo/xcsh:vX.Y.Z\ndocker image inspect --format '{{index .RepoDigests 0}}' ghcr.io/f5-sales-demo/xcsh:vX.Y.Z\ndocker run --rm ghcr.io/f5-sales-demo/xcsh@sha256:<digest> --version\n```\n\nPodman accepts the same pull, inspect, and run arguments. Pass provider credentials at runtime through a secret manager or environment file; never bake them into an image layer.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nPull a newer pinned tag to upgrade. Remove an unused image with `docker image rm IMAGE` or `podman image rm IMAGE`.\n</details>\n</TabItem>\n\n<TabItem label=\"Packages and source\" icon=\"seti:config\">\nUse a JavaScript package or a source/ref install when you need a toolchain or an unreleased ref. Source installs require Git and Bun 1.4.2 or newer:\n\n```bash\nbun install --global @f5-sales-demo/xcsh\nnpm install --global @f5-sales-demo/xcsh\ncurl -fsSL https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.sh \\\n | sh -s -- --source --ref vX.Y.Z\n```\n\nThe explicit `--source` and `--ref` arguments select a reproducible source install.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `bun update --global @f5-sales-demo/xcsh` or\n`npm update --global @f5-sales-demo/xcsh`. `xcsh self-update` reports the matching\ncommand for a validated compiled-release launcher but never invokes the package\nmanager. Remove the package with `bun remove --global @f5-sales-demo/xcsh` or\n`npm uninstall --global @f5-sales-demo/xcsh`; re-run the source command at a new\nref to replace that unsupported development channel.\n</details>\n</TabItem>\n</Tabs>\n\nRun `xcsh self-update --check` for a read-only version and installation-channel report. A direct MDM package remains organization-managed. Missing, stale, spoofed, or conflicting provenance is blocked without downloading, invoking a package manager, or changing the executable; reinstall through the documented channel instead of mixing installers.\n\nWhichever installation channel you choose, open xcsh next.\n\n<span id=\"verification\" aria-hidden=\"true\"></span>\n\n## Verify installation\n\n<span id=\"verify-the-active-installation\" aria-hidden=\"true\"></span>\n\nStart the interactive terminal UI:\n\n<div class=\"landing-command\">\n\n```bash\nxcsh\n```\n\n</div>\n\nWhen the xcsh prompt appears, connect a model provider from inside the TUI.\n\n<span id=\"authentication\" aria-hidden=\"true\"></span>\n\n## Authenticate a provider\n\nAt the xcsh prompt, open the provider picker:\n\n<div class=\"landing-command\">\n\n```text\n/login\n```\n\n</div>\n\nChoose a provider and follow its sign-in flow. You can also enter `/login PROVIDER` to open a known provider directly. Keep credentials in the provider-supported environment or subscription login—never in a prompt or committed settings file. See [model authentication](/xcsh/en/getting-started/model-authentication/) for provider-specific options.\n\nGPT-6 Luna and Sol use a 272K-token context window by default for ChatGPT subscription sessions.\nTo opt in to their published 1.05M-token window, open `/settings`, select **Providers**, and enable\n**OpenAI Codex Maximum Context**. OpenAI applies higher token pricing to requests above 272K.\nInternal LiteLLM GPT routes use the same 272K default independently; enable **LiteLLM Maximum\nContext** to opt those routes into their verified 1.05M-token window.\n\nAfter sign-in selects a model, stay in the TUI and send a small first prompt.\n\n## Quickstart\n\nAt the xcsh prompt, enter:\n\n<div class=\"landing-command\">\n\n```text\nReply with only: xcsh is ready\n```\n\n</div>\n\nA matching response confirms the installation, provider, and selected model are working together\nwithout granting a tool any file or network side effect. If it fails, verify the active executable\nwith `command -v xcsh`, reopen `/login`, and confirm the selected model is available to that\naccount. Next, learn the [interactive TUI](/xcsh/en/use-xcsh/interactive-tui/) or choose a [context and\nnamespace](/xcsh/en/f5-distributed-cloud/contexts-namespaces/) before an authorized F5 Distributed Cloud\nchange.\n\nFrom here, continue with the documentation path that matches your goal.\n\n<span id=\"exploration\" aria-hidden=\"true\"></span>\n\n## Explore by goal\n\nChoose the goal closest to your next task; each path starts from the verified installation above.\n\n<div class=\"landing-grid landing-explore\">\n <LinkCard title=\"Use xcsh\" icon=\"terminal\" href=\"./use-xcsh/\">Daily terminal use, tools, sessions, plans, and agents.</LinkCard>\n <LinkCard title=\"F5 Distributed Cloud\" icon=\"cloud\" href=\"./f5-distributed-cloud/\">Contexts, manifests, validation, and reviewable resource changes.</LinkCard>\n <LinkCard title=\"Configure and secure\" icon=\"setting\" href=\"./configure-secure/\">Providers, settings, secrets, and sandbox boundaries.</LinkCard>\n <LinkCard title=\"Automate and extend\" icon=\"puzzle\" href=\"./automate-extend/\">Headless modes, extensions, skills, plugins, and SDKs.</LinkCard>\n <LinkCard title=\"Integrations and deployment\" icon=\"rocket\" href=\"./integrations-deployment/\">Containers plus VS Code, Chrome, Office, and Herdr.</LinkCard>\n <LinkCard title=\"Reference and troubleshooting\" icon=\"information\" href=\"./reference-troubleshooting/\">Diagnostics, command reference, hotkeys, and configuration schema.</LinkCard>\n</div>\n",
43
+ "en/index.mdx": "---\ntitle: xcsh\ndescription: Install xcsh, authenticate a model provider, and begin a reviewable terminal or F5 Distributed Cloud workflow.\ntemplate: splash\neditUrl: false\nsidebar:\n hidden: true\n order: 0\nhead:\n - tag: style\n content: |\n main:has(.landing-hero) > .content-panel:first-of-type { padding-block-end: .5rem; }\n main:has(.landing-hero) > .content-panel:first-of-type + .content-panel { border-top: 0; padding-block-start: 0; }\n .landing-hero { display: grid; gap: clamp(2rem, 4vw, 4rem); grid-template-columns: minmax(0, 1fr) minmax(18rem, 35rem); align-items: center; margin-block: .75rem 2rem; }\n .landing-hero__content, .landing-hero__image, .landing-installer, .landing-installer .expressive-code, .landing-command { min-width: 0; }\n h1#_top { max-width: 13ch; margin-block-end: 0; text-wrap: balance; }\n .landing-hero__lede { max-width: 42rem; color: var(--sl-color-gray-2); font-size: var(--sl-text-lg); }\n .landing-installer { margin-block: 0 4rem; padding: clamp(1rem, 2vw, 1.5rem); border: 1px solid var(--sl-color-gray-5); border-radius: .75rem; background: var(--sl-color-bg-nav); }\n .landing-installer h2 { margin: 0; font-size: var(--sl-text-lg); }\n .landing-installer p { margin-block: .5rem 0; }\n .landing-installer pre { max-width: 100%; overflow-x: auto; }\n .landing-installer .expressive-code .ec-line .code { padding-inline-end: 3.5rem; white-space: pre; overflow-wrap: normal; }\n .landing-installer .expressive-code .copy button { opacity: 1; }\n .landing-hero__image { margin: 0; }\n .landing-hero__image img { display: block; width: 100%; height: auto; aspect-ratio: 1442 / 1268; object-fit: contain; filter: drop-shadow(0 1rem 2.5rem color-mix(in srgb, var(--sl-color-accent) 28%, transparent)); }\n .landing-grid { display: grid; gap: 1rem; grid-template-columns: repeat(3, minmax(0, 1fr)); margin-block: 1.5rem; }\n .landing-explore { grid-template-columns: repeat(2, minmax(0, 1fr)); }\n details.landing-disclosure { margin-block: 1rem 0; padding: .75rem 1rem; border: 1px solid var(--sl-color-gray-5); border-radius: .5rem; background: var(--sl-color-bg-nav); }\n details.landing-disclosure summary { cursor: pointer; font-weight: 600; }\n :is(.landing-hero, .landing-installer, .landing-grid, .landing-disclosure) :is(a, button, summary):focus-visible { outline: 2px solid var(--sl-color-accent-high); outline-offset: 3px; }\n @media (max-width: 50rem) { .landing-hero { grid-template-columns: minmax(0, 1fr); gap: 2rem; margin-block: .5rem 2rem; } .landing-installer { margin-block-end: 3rem; padding: 1rem; } .landing-grid { grid-template-columns: minmax(0, 1fr); } }\n---\n\nimport { Aside, Card, LinkCard, TabItem, Tabs } from '@astrojs/starlight/components';\n\n<section class=\"landing-hero\" aria-labelledby=\"_top\">\n <div class=\"landing-hero__content\">\n <p class=\"landing-hero__lede\">An AI-native terminal assistant for engineering, automation, and reviewable F5 Distributed Cloud workflows.</p>\n <p>xcsh is an independent open-source project derived from pi/pi-mono, specialized for F5 Distributed Cloud workflows; it is not an F5 product.</p>\n </div>\n\n <figure class=\"landing-hero__image\">\n <img src=\"/xcsh/images/xcsh-ghostty-terminal.png\" width=\"1442\" height=\"1268\" alt=\"xcsh running in a Ghostty terminal with the model selector, prompt, and session status visible.\" />\n </figure>\n</section>\n\n<section class=\"landing-installer\" aria-labelledby=\"install-xcsh\">\n\n## Install xcsh\n\n <p>Universal installer for macOS and Linux.</p>\n\n ```bash\n curl -fsSL https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.sh | sh\n ```\n\n <p>It installs the latest prebuilt release and a schema-v2 provenance receipt into <code>~/.local/bin</code>. The native addon is embedded in the executable, so those are the only two standalone payloads. This is the only channel that <code>xcsh self-update</code> replaces in process. Need a managed or platform-specific channel? Compare the <a href=\"#installation-options\">installation options</a>.</p>\n</section>\n\n## What xcsh helps you do\n\n<div class=\"landing-grid landing-capabilities\">\n <Card title=\"Agentic terminal work\" icon=\"terminal\">\n Run interactive or print-mode prompts, inspect files, use tools, and keep durable session history when the task needs it. [Learn the agent loop](/xcsh/en/use-xcsh/agent-loop/).\n </Card>\n <Card title=\"Reviewable F5 Distributed Cloud workflows\" icon=\"document\">\n Discover schemas, validate manifests, and inspect proposed differences before an authorized resource change. [Use resource workflows](/xcsh/en/f5-distributed-cloud/).\n </Card>\n <Card title=\"Extensible automation\" icon=\"puzzle\">\n Add headless workflows, custom tools, skills, or plugins when built-in commands are not enough. [Automate and extend](/xcsh/en/automate-extend/).\n </Card>\n</div>\nThese workflows start with a working executable; choose another channel only when the universal installer is not the right fit.\n\n## Installation options\n\nUse one channel for install and upgrades. Mixing package-manager and standalone installations can leave more than one `xcsh` on `PATH`; the universal installer above is not repeated here.\n\n<Tabs syncKey=\"install-platform\">\n<TabItem label=\"macOS\" icon=\"seti:apple\">\nInstall the signed and notarized macOS archive through the Homebrew cask. The cask preserves the released executable and native addon byte for byte and does not require `sudo`:\n\n```bash\nbrew install --cask f5-sales-demo/tap/xcsh\n```\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `brew upgrade --cask f5-sales-demo/tap/xcsh`. Remove the cask with `brew uninstall --cask xcsh`. `xcsh self-update` reports the tap-qualified command but never invokes Homebrew. These commands preserve configuration, credentials, and sessions under `~/.xcsh`.\n</details>\n\n<Aside type=\"caution\" title=\"Clean break from the historical package cask\">\nBefore installing this cask on a Mac that received an earlier xcsh package,\nuninstall both old Homebrew entries (`brew uninstall --formula xcsh` and\n`brew uninstall --cask xcsh`). Then have MDM forget the `com.f5.xcsh` receipt\nand remove only the package-owned `/usr/local/bin/xcsh` and\n`/Library/Application Support/xcsh` payload. Do not remove `~/.xcsh`. The signed\nand stapled `.pkg` release assets remain available only for direct MDM\ndeployment.\n</Aside>\n</TabItem>\n\n<TabItem label=\"Ubuntu or Debian\" icon=\"seti:ubuntu\">\nThe signed apt repository supports amd64 and arm64 and follows normal system upgrades:\n\n```bash\nsudo install -d -m 0755 /etc/apt/keyrings\ncurl -fsSL https://f5-sales-demo.github.io/apt-repo/f5xc-archive-keyring.gpg \\\n | sudo tee /etc/apt/keyrings/f5xc-archive-keyring.gpg >/dev/null\necho \"deb [arch=amd64,arm64 signed-by=/etc/apt/keyrings/f5xc-archive-keyring.gpg] https://f5-sales-demo.github.io/apt-repo stable main\" \\\n | sudo tee /etc/apt/sources.list.d/f5xc.list\nsudo apt-get update && sudo apt-get install xcsh\n```\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `sudo apt-get update && sudo apt-get install --only-upgrade xcsh`. Remove the package with `sudo apt-get remove xcsh`. `xcsh self-update` reports this command when `dpkg-query` proves that package `xcsh` owns the running executable; it never invokes apt.\n</details>\n</TabItem>\n\n<TabItem label=\"Windows\" icon=\"seti:windows\">\nRun the PowerShell installer, then restart the terminal so its user `PATH` refreshes:\n\n```powershell\nirm https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.ps1 | iex\n```\n\nIt installs `xcsh.exe` and its schema-v2 provenance receipt to `%LOCALAPPDATA%\\\\xcsh`; the native addon is embedded. **Bash is required for tool-backed sessions.** Install Git for Windows, WSL, Cygwin, or MSYS2; set `shellPath` in `%USERPROFILE%\\\\.xcsh\\\\agent\\\\settings.json` when Bash is elsewhere.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nRe-run the installer to upgrade. `xcsh self-update` reports the PowerShell installer command but does not replace a Windows installer-owned executable. To uninstall, remove `%LOCALAPPDATA%\\\\xcsh` and its entry from the user `PATH`.\n</details>\n</TabItem>\n\n<TabItem label=\"Container\" icon=\"seti:docker\">\nDocker and Podman use the same multi-architecture image. Pin a release tag, resolve its digest for deployment, and mount only the workspace and state required by the task:\n\n```bash\ndocker pull ghcr.io/f5-sales-demo/xcsh:vX.Y.Z\ndocker image inspect --format '{{index .RepoDigests 0}}' ghcr.io/f5-sales-demo/xcsh:vX.Y.Z\ndocker run --rm ghcr.io/f5-sales-demo/xcsh@sha256:<digest> --version\n```\n\nPodman accepts the same pull, inspect, and run arguments. Pass provider credentials at runtime through a secret manager or environment file; never bake them into an image layer.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nPull a newer pinned tag to upgrade. Remove an unused image with `docker image rm IMAGE` or `podman image rm IMAGE`.\n</details>\n</TabItem>\n\n<TabItem label=\"Packages and source\" icon=\"seti:config\">\nUse a JavaScript package or a source/ref install when you need a toolchain or an unreleased ref. Source installs require Git and Bun 1.4.2 or newer:\n\n```bash\nbun install --global @f5-sales-demo/xcsh\nnpm install --global @f5-sales-demo/xcsh\ncurl -fsSL https://raw.githubusercontent.com/f5-sales-demo/xcsh/main/scripts/install.sh \\\n | sh -s -- --source --ref vX.Y.Z\n```\n\nThe explicit `--source` and `--ref` arguments select a reproducible source install.\n\n<details class=\"landing-disclosure\">\n<summary>Upgrade or remove</summary>\n\nUpgrade with `bun update --global @f5-sales-demo/xcsh` or\n`npm update --global @f5-sales-demo/xcsh`. `xcsh self-update` reports the matching\ncommand for a validated compiled-release launcher but never invokes the package\nmanager. Remove the package with `bun remove --global @f5-sales-demo/xcsh` or\n`npm uninstall --global @f5-sales-demo/xcsh`; re-run the source command at a new\nref to replace that unsupported development channel.\n</details>\n</TabItem>\n</Tabs>\n\nRun `xcsh self-update --check` for a read-only version and installation-channel report. A direct MDM package remains organization-managed. Missing, stale, spoofed, or conflicting provenance is blocked without downloading, invoking a package manager, or changing the executable; reinstall through the documented channel instead of mixing installers.\n\n<Aside type=\"caution\" title=\"Standalone receipt schema v2\">\nStandalone installations with an older schema-v1 receipt must run the documented installer once before using `xcsh self-update`. There is no compatibility parser or automatic receipt migration. A successful self-update advances the executable and adjacent receipt together and restores both if the transaction fails.\n</Aside>\n\nWhichever installation channel you choose, open xcsh next.\n\n<span id=\"verification\" aria-hidden=\"true\"></span>\n\n## Verify installation\n\n<span id=\"verify-the-active-installation\" aria-hidden=\"true\"></span>\n\nStart the interactive terminal UI:\n\n<div class=\"landing-command\">\n\n```bash\nxcsh\n```\n\n</div>\n\nWhen the xcsh prompt appears, connect a model provider from inside the TUI.\n\n<span id=\"authentication\" aria-hidden=\"true\"></span>\n\n## Authenticate a provider\n\nAt the xcsh prompt, open the provider picker:\n\n<div class=\"landing-command\">\n\n```text\n/login\n```\n\n</div>\n\nChoose a provider and follow its sign-in flow. You can also enter `/login PROVIDER` to open a known provider directly. Keep credentials in the provider-supported environment or subscription login—never in a prompt or committed settings file. See [model authentication](/xcsh/en/getting-started/model-authentication/) for provider-specific options.\n\nGPT-6 Luna and Sol use a 272K-token context window by default for ChatGPT subscription sessions.\nTo opt in to their published 1.05M-token window, open `/settings`, select **Providers**, and enable\n**OpenAI Codex Maximum Context**. OpenAI applies higher token pricing to requests above 272K.\nInternal LiteLLM GPT routes use the same 272K default independently; enable **LiteLLM Maximum\nContext** to opt those routes into their verified 1.05M-token window.\n\nAfter sign-in selects a model, stay in the TUI and send a small first prompt.\n\n## Quickstart\n\nAt the xcsh prompt, enter:\n\n<div class=\"landing-command\">\n\n```text\nReply with only: xcsh is ready\n```\n\n</div>\n\nA matching response confirms the installation, provider, and selected model are working together\nwithout granting a tool any file or network side effect. If it fails, verify the active executable\nwith `command -v xcsh`, reopen `/login`, and confirm the selected model is available to that\naccount. Next, learn the [interactive TUI](/xcsh/en/use-xcsh/interactive-tui/) or choose a [context and\nnamespace](/xcsh/en/f5-distributed-cloud/contexts-namespaces/) before an authorized F5 Distributed Cloud\nchange.\n\nFrom here, continue with the documentation path that matches your goal.\n\n<span id=\"exploration\" aria-hidden=\"true\"></span>\n\n## Explore by goal\n\nChoose the goal closest to your next task; each path starts from the verified installation above.\n\n<div class=\"landing-grid landing-explore\">\n <LinkCard title=\"Use xcsh\" icon=\"terminal\" href=\"./use-xcsh/\">Daily terminal use, tools, sessions, plans, and agents.</LinkCard>\n <LinkCard title=\"F5 Distributed Cloud\" icon=\"cloud\" href=\"./f5-distributed-cloud/\">Contexts, manifests, validation, and reviewable resource changes.</LinkCard>\n <LinkCard title=\"Configure and secure\" icon=\"setting\" href=\"./configure-secure/\">Providers, settings, secrets, and sandbox boundaries.</LinkCard>\n <LinkCard title=\"Automate and extend\" icon=\"puzzle\" href=\"./automate-extend/\">Headless modes, extensions, skills, plugins, and SDKs.</LinkCard>\n <LinkCard title=\"Integrations and deployment\" icon=\"rocket\" href=\"./integrations-deployment/\">Containers plus VS Code, Chrome, Office, and Herdr.</LinkCard>\n <LinkCard title=\"Reference and troubleshooting\" icon=\"information\" href=\"./reference-troubleshooting/\">Diagnostics, command reference, hotkeys, and configuration schema.</LinkCard>\n</div>\n",
44
44
  "en/integrations-deployment/chrome.mdx": "---\ntitle: \"Chrome\"\ndescription: \"Use the xcsh Chrome extension and native host with an isolated automation profile.\"\nsidebar:\n order: 3\n label: \"Chrome\"\n---\n\nThe Chrome integration connects xcsh to a browser session for supported console automation. The installed `xcsh chrome --help` output is the command authority.\n\n## What is the safe operating boundary?\n\nUse a dedicated profile and an authorized target. Confirm the visible account, uniform resource locator (URL), and object before an action that changes state. Prefer deterministic F5 Distributed Cloud resource commands whenever they cover the same operation.\n\n## Which Chrome capabilities does xcsh expose?\n\nThe `chrome` command inspects and arranges browser sessions, and `chrome-host` runs the native messaging host that connects the extension to the executable. Page-level interaction is driven by the browser tool inside a session rather than by a subcommand, so scope it with `--tools` in the same way as any other tool.\n\n| Need | Use Chrome integration? | Boundary |\n| --- | --- | --- |\n| Inspect a visible page or perform a supported console-only task | Yes | The browser profile and signed-in session define authority. |\n| Manage a resource with an xcsh catalog command | No | Prefer the typed resource workflow and its diff. |\n| Automate an unsupported site or a third-party account | No | The integration does not expand authorization. |\n\nStart with a read-only inspection and confirm the selected tab, URL, tenant, and browser profile. A click or submitted form can create an external side effect; the transcript must identify that boundary. Close temporary tabs and verify the intended page state after the task.\n",
45
45
  "en/integrations-deployment/containers.mdx": "---\ntitle: \"Containers\"\ndescription: \"Run the published multi-architecture Alpine image with explicit mounts and credentials.\"\nsidebar:\n order: 4\n label: \"Containers\"\nhead:\n - tag: style\n content: |\n .sl-markdown-content .expressive-code { max-width: 100%; overflow-x: auto; }\n .sl-markdown-content table { display: block; max-width: 100%; overflow-x: auto; }\n---\n\nThe published container packages xcsh for process isolation and repeatable deployment. It does not grant cloud credentials or filesystem access by itself.\n\n## How do I verify an image?\n\n```bash\ndocker pull ghcr.io/f5-sales-demo/xcsh:latest\ndocker run --rm ghcr.io/f5-sales-demo/xcsh:latest --version\n```\n\nPin a version tag or digest for automation. Mount only the task directory and inject credentials through the runtime's secret mechanism.\n\n## What must remain outside the image?\n\nKeep user contexts, provider tokens, and writable session data in explicit mounts or secret stores. Do not bake them into a derived layer.\n\nPull a versioned image, resolve its immutable digest, and run `xcsh --version` from that digest\nbefore mounting a workspace. The container image supplies the executable, not model or tenant\nauthority. Mount only required paths read-only where possible and inject credentials at runtime\nthrough the platform's secret mechanism. Remove the test container after exit; delete the pinned\nimage only when no deployment still references its digest.\n",
46
46
  "en/integrations-deployment/herdr.mdx": "---\ntitle: \"Integrate with Herdr\"\ndescription: \"Understand Herdr workspace launch, terminal actions, protocol negotiation, and isolation.\"\nsidebar:\n order: 5\n label: \"Herdr\"\nhead:\n - tag: style\n content: |\n .sl-markdown-content .expressive-code { max-width: 100%; overflow-x: auto; }\n .sl-markdown-content table { display: block; max-width: 100%; overflow-x: auto; }\n---\n\nHerdr support is optional and host-dependent. When the host does not provide it, xcsh terminal operation is unaffected.\n\n## How is the host protocol negotiated?\n\nThe integration checks the available socket protocol and media or graphics capabilities before it requests a workspace. Missing negotiation support leaves ordinary xcsh terminal operation intact.\n\n## How is a conversation-owned workspace launched?\n\nA workspace is tied to the conversation identity supplied at startup. Terminal-management actions create or address panes within that workspace, and lifecycle reporting stays anchored to the same startup context. Do not reuse an unrelated workspace merely because its socket is reachable.\n\n## How do I recover from socket failure?\n\nConnection and framing failures surface as integration diagnostics. The client must not open an inbound listener as a fallback. Close conversation-owned resources through the supported lifecycle and preserve unrelated Herdr workspaces.\n\n## What lifecycle state does xcsh publish?\n\nxcsh publishes native turn phases rather than inferring completion from terminal idleness or process\nexit. With a supported Herdr protocol through 26 and the advertised `agent_turn_journal` capability, a tracked\nexecution publishes a persisted session/turn identity and a bounded semantic result to Herdr's\ndurable journal. The existing 80-character metadata preview remains display-only and is never\ncompletion evidence.\nCommentary, prompt content, tool data, and failed or cancelled partial output are excluded.\n\n### External execution driver contract\n\nThe supported producer is the normal `xcsh` executable launched by Herdr's execution backend; it is not a mock or a no-provider/offline actor. For a journal-tracked invocation, that backend must inject the exact allocated `HERDR_EXECUTION_ID` and decimal safe-integer `HERDR_EXECUTION_GENERATION` into the child environment before it starts `xcsh`.\n\nxcsh never guesses a generation: without both values it retains ordinary pane lifecycle reporting but emits no semantic journal event. A continuation must be launched with its newly allocated generation.\n\nProtocol 27 is the current producer-native contract. Herdr injects a one-time `HERDR_NATIVE_CAPABILITY` into the child. xcsh includes it only in authenticated turn-report and action requests; it is never written to the session journal, logs, diagnostics, or receipts.\nHerdr does not authorize actions until the first `starting` report has been durably journaled and bound to the owned PTY, pane, session, generation, and turn.\n\nEach semantic report has a five-second deadline. xcsh retries exactly once only when timeout,\nEOF, or a transport error leaves admission ambiguous. The retry preserves the method and complete\nsemantic payload and changes only the transport request ID. Either correlated receipt marks the\nevent delivered; protocol, validation, malformed-response, and explicit remote errors are definitive\nand are not retried. Degraded tracking is shown only after both ambiguous attempts fail.\n\nThe producer wire shapes align with [Herdr PR #49](https://github.com/f5-sales-demo/herdr/pull/49) at cancellation-settlement commit `2c838cf545ed06439b4988cedb3e044f1d436264`, starting-replay recovery commit `edd5611cfd7685c0f069f244ceee0ac6c0a0678e`, and native-argv alignment commit `3397302960593a552fb37ceb71053cf99f2619a3`.\nThose commits are an integration contract under independent review, not released-backend evidence.\n\nAfter that registration, xcsh polls `agent.turn.action.get` with the same immutable provenance. A `cancel` action dismisses an active managed UI prompt and calls the real `AgentSession` abort path. xcsh persists the requested action and local safe point before sending the exact `agent.turn.action.ack`; it emits `cancelled` only after Herdr confirms that safe point.\nA lost ACK response is retried with the same action ID and revision, including after reporter restart. A backend `timed_out` action never triggers a late abort. PTY exit alone is not semantic cancellation.\n\nSession shutdown releases pane authority. It does not convert an unfinished turn into a successful completion.\n\n### Producer-native acceptance driver\n\n`xcsh lifecycle --json` prints the version 3 machine-readable producer contract. To execute a source or installed\nproducer check, supply a fresh absolute session directory, a normally configured model, and one scenario:\n\n```bash\nxcsh lifecycle --json \\\n --scenario await-continue \\\n --model openai-codex/gpt-5.6-luna \\\n --session-dir /absolute/fresh/xcsh-lifecycle-session\n```\n\nSupported scenarios are `success`, `failure`, `await-continue`, `cancel`, `managed-cancel`, `managed-working-cancel`, `local-operation-failure`, and `reply-loss-replay`. The driver first\nuses the prompt-free JSON session contract to persist one canonical 16-character lowercase hexadecimal session\nheader, then reopens that exact path in an ordinary interactive xcsh child. It generates a random mode-0600 fixture\nfor successful reads. `await-continue` selects the explicit `await_user_v1` producer control and pauses in the real\n`ExtensionUIController` input surface before the configured\nmodel runs; `cancel` sends SIGINT through `PtySession.interrupt()` and requires xcsh's native `cancelled` transition.\n`managed-cancel` uses a local protocol-27 control fixture to request the action and requires the executable child to\nacknowledge its safe point before its native `cancelled` report. That fixture validates the producer adapter only; it\nis not evidence for Herdr's durable action journal, manager generation replacement, or consumer deduplication.\n`managed-working-cancel` requests the same cooperative action after the real child reports `working`, without opening\nthe acceptance prompt, and verifies cancellation through the active `AgentSession` path.\n`local-operation-failure` selects `local_operation_failure_v1` in a noninteractive native child. The producer creates\na private directory under the child cwd, performs a real read of a guaranteed-missing path inside it, cleans up the\nowned directory, and propagates the resulting ENOENT through normal `AgentSession` failed settlement. It does not use\nan invalid credential, an offline model, or a fabricated lifecycle frame.\n\nThe producer accepts these exact explicit argv mappings; no control is active when the flag is omitted. The published\n`await-user` spelling remains an alias for `await_user_v1` for existing acceptance callers.\n\n| Typed lifecycle mode | Producer argv | Constraint |\n| --- | --- | --- |\n| `managed_turn_v1` | no additional argv | Existing protocol-27 v3 behavior. |\n| `await_user_v1` | `--native-lifecycle-control await_user_v1` | `interactive: true`. |\n| `local_operation_failure_v1` | `--native-lifecycle-control local_operation_failure_v1` | `interactive: false`. |\n\nThe current Herdr protocol-27 schema exposes only `managed_turn_v1`; the other two rows define the producer side of a\nfuture typed schema extension, not permission for a caller to supply arbitrary argv. xcsh does not invent action\nmethods for response loss or restart. Real Herdr-bound retry and restart controls must use a committed authenticated\nbackend schema and preserve the same session, generation, pane, turn, report revision, and request-only capability.\n\nThe reply-loss scenario owns a temporary local protocol-27 socket that acknowledges ordinary reporter traffic but\ndrops both bounded `agent.turn.report` attempts. xcsh creates and persists the semantic event before transport, runs the\nconfigured provider and `read` tool, then a second xcsh process resumes the exact session path. The scenario passes\nonly when the reporter redelivers the byte-equivalent execution, pane, session, turn, generation, event revision, and\nstate fields. The socket never authors a lifecycle frame or substitutes an offline model.\n\nThe receipt's `evidenceClass` is `source_native_child`. This proves the measured source or executable behavior only;\nthe Control Manager remains responsible for its own admission, authenticated execution binding, generation changes,\nconsumer receipts, and installed-artifact acceptance. The command does not install or release xcsh or Herdr and does\nnot change normal launch defaults.\n\nThe verified contract is:\n\n| Concern | xcsh signal | Herdr disposition |\n| --- | --- | --- |\n| Session start and identity | Persisted native session ID/path | Herdr resume reference plus stable semantic session identity. |\n| Turn start/progress | Persisted UUID and normalized `turn_phase` | `starting`/`working` journal events with producer revision and server revision. |\n| Waiting for input/approval | `awaiting_user` and closed prompt kind | `waiting_input` with fixed safe reason; private prompt content is excluded. |\n| Successful completion | Settlement-aware `idle` after `agent_end` | `completed` with at most 8,000 UTF-8 bytes and a matching SHA-256 digest. |\n| Failure/cancellation | `error` or `cancelled` | Distinct terminal state and bounded safe reason; no partial result. |\n| Managed cancellation | Persisted action receipt, Extension UI signal, and `AgentSession.abort()` | Authenticated `safe_point` precedes and is linked to the native `cancelled` report. |\n| Resume/fork | Session events and persisted custom turn entries | Resume preserves identity; unfinished recovered work becomes `interrupted`; fork has separate session lineage. |\n| Reconnect/order | Serialized queue and persisted event revision | Exact duplicates are idempotent; stale/conflicting revisions fail; terminal state is immutable. |\n| Application exit | `session_shutdown` | Active turn becomes `interrupted`, then pane authority is released; never success. |\n\nThe protocol-26 native-interaction update is tracked by\n[issue #4161](https://github.com/f5-sales-demo/xcsh/issues/4161); its producer lifecycle foundation is\ntracked by [issue #3791](https://github.com/f5-sales-demo/xcsh/issues/3791) and\n[issue #3768](https://github.com/f5-sales-demo/xcsh/issues/3768). The active protocol and lifecycle\nbehavior is described on this page; obsolete delivery checklists are not part of the runtime contract.\n\nHerdr lifecycle reconciliation is tracked by issue #5 in the F5 Herdr fork. Current source already recognizes the exact `(\"herdr:xcsh\", \"xcsh\")` resume pair; deployed build provenance and live resume/fork acceptance remain required before feature acceptance.\n\nTreat the negotiated protocol and the pane lifecycle as separate checks. First confirm that the\nHerdr socket and protocol version are compatible, then launch one conversation-owned workspace and\nobserve its published state through exit. xcsh owns only workspaces it created for that\nconversation; it must not close unrelated panes. After a forced socket failure, reconnect and verify\nthat stale workspace state is reconciled before another launch.\n",
47
47
  "en/integrations-deployment/index.mdx": "---\ntitle: \"Integrations and deployment\"\ndescription: \"Deploy xcsh in containers and connect the editor, browser, Office, and Herdr surfaces.\"\nsidebar:\n order: 0\n label: \"Integrations\"\n---\n\nChoose an integration by host, authority, and lifecycle boundary.\n\n## Which integration fits?\n\n- [Containers](/xcsh/en/integrations-deployment/containers/) for an isolated packaged runtime.\n- [VS Code](/xcsh/en/integrations-deployment/vscode/), [Chrome](/xcsh/en/integrations-deployment/chrome/), [Office](/xcsh/en/integrations-deployment/office/), or [Herdr](/xcsh/en/integrations-deployment/herdr/) only when that companion surface is installed and the task needs it.\n",
48
48
  "en/integrations-deployment/office.mdx": "---\ntitle: \"Microsoft Office task pane\"\ndescription: \"Serve or sideload the embedded task pane for Excel, Word, and PowerPoint.\"\nsidebar:\n order: 2\n label: \"Office task pane\"\n---\n\nThe Office pane packages an xcsh sidebar for supported Excel, Word, and PowerPoint hosts. `xcsh office --help` describes the installed serve, print, and sideload actions.\n\n## Who owns the test surface?\n\nPackage tests own pane components, bridge messages, and host-independent state. Office-host integration tests own document application programming interfaces (APIs), sideloading, and task-pane lifecycle. A change that crosses the bridge requires both suites; a passing browser-style component test does not prove Word, Excel, or PowerPoint host behavior.\n\n## What must be running?\n\nThe pane build and its local bridge server must match the xcsh version used for the session. One active sidebar binds to one server session at a time.\n\n## Which host steps vary by platform?\n\nRibbon placement, the sideload mechanism, and trust prompts differ across Office on Windows, Office on macOS, and Office on the web. Read the sideload action from `xcsh office --help`, then follow the Microsoft sideloading procedure for the specific host you are targeting.\n\n| Goal | Recommended surface | Why |\n| --- | --- | --- |\n| Edit or analyze a standalone document | The document workflow | It can render and verify the saved artifact. |\n| Control the open Office task pane | The Office integration | It operates in the signed-in host application. |\n| Run a repeatable batch job | Headless mode or SDK | It avoids UI-dependent focus and selection. |\n\nThe Office host, active document, selection, and signed-in account determine scope. Confirm all four before a write. Save to a test copy, reopen it, and inspect the changed region; closing a dialog is not proof that the document persisted.\n",
49
49
  "en/integrations-deployment/vscode.mdx": "---\ntitle: \"VS Code\"\ndescription: \"Use the companion VS Code integration with the same xcsh model and session foundation.\"\nsidebar:\n order: 1\n label: \"VS Code\"\n---\n\nThe companion VS Code extension embeds an xcsh conversation in an editor workspace. Its extension manifest and source repository define the supported commands and distribution channel.\n\n## What carries over from the terminal?\n\nProvider configuration, model selection, session concepts, and workspace file boundaries follow the xcsh runtime. Open the intended workspace before starting a conversation.\n\n## Which behavior should I validate in the terminal?\n\nEditor menus and command palette entries belong to the extension host and change with its release. Reproduce runtime behavior with the command-line interface (CLI) first:\n\n1. Run the same prompt with `xcsh -p` in the workspace directory.\n2. Compare the model, provider, and tool set reported there with the editor session.\n3. Inspect the persisted session file rather than the editor transcript when an exact sequence matters.\n\nA difference between the two points at extension configuration, not at the agent loop.\n\n| Need | Use VS Code? | Alternative |\n| --- | --- | --- |\n| Work with editor selection and workspace context | Yes | The terminal cannot infer the active editor selection. |\n| Reproduce provider, tool, or session behavior | Usually no | Reproduce with the xcsh CLI first. |\n| Run unattended automation | No | Use a headless protocol or the SDK. |\n\nThe extension inherits the VS Code workspace trust and process environment but still uses xcsh provider and tool boundaries. Confirm the workspace root and selected file before applying an edit. Re-run the same prompt in the terminal when isolating whether a failure belongs to xcsh or the editor host.\n",
50
- "en/reference-troubleshooting/cli-reference.mdx": "---\ntitle: \"CLI command and flag reference\"\ndescription: \"Look up every top-level xcsh command and every global flag a session accepts.\"\nsidebar:\n order: 1\n label: \"CLI reference\"\n---\n\nThe installed `xcsh <COMMAND> --help` output is the command-line interface (CLI) authority for its release. This page lists the command and flag names that release exposes so you can find one without starting a session.\n\n## Which top-level commands exist?\n\n| Area | Commands |\n| --- | --- |\n| Resources | `validate`, `diff`, `create`, `apply`, `update`, `get`, `export`, `delete` |\n| Runtime | `config`, `setup`, `sandbox`, `shell`, `ssh`, `stats`, `search` |\n| Files and code | `read`, `grep`, `jupyter` |\n| Extensibility | `agents`, `plugin`, `worker`, `manager` |\n| Interfaces | `chrome`, `chrome-host`, `office`, `herdr` |\n| Repository | `commit`, `grievances` |\n| Maintenance | `self-update` |\n\n`search` also answers to `q`. `update -f` names a resource manifest; executable checks and updates use `self-update`.\n\n`xcsh self-update --check` is read-only and reports the installation channel. Homebrew,\napt, npm, Bun, Windows installer, and direct MDM installations retain ownership:\nthe command prints their exact upgrade instruction or managed-install message and\nperforms no update. Only a standalone Unix executable with a valid adjacent\n`xcsh-install.json` receipt can replace itself. Unknown or conflicting provenance\nexits nonzero without changing files, and `--force` does not bypass this policy.\n\n## Which global flags does a session accept?\n\nThese flags configure an agent launch. They precede the prompt and do not apply to a subcommand.\n\n| Group | Flags |\n| --- | --- |\n| Model | `--model`, `--smol`, `--slow`, `--plan`, `--provider`, `--models`, `--thinking`, `--list-models` |\n| Credentials and context | `--api-key`, `--context` |\n| Prompt | `--system-prompt`, `--append-system-prompt`, `--no-title` |\n| Mode | `--mode` (`text`, `json`, `rpc`, `acp`), `-p`/`--print` |\n| Session | `-c`/`--continue`, `-r`/`--resume`, `--fork`, `--session-dir`, `--no-session`, `--no-memories`, `--export` |\n| Filesystem | `--allow-home`, `--allow-path`, `--no-sandbox` |\n| Capabilities | `--tools`, `--no-tools`, `--no-lsp`, `--no-pty` |\n| Discovery | `-e`/`--extension`, `--hook`, `--plugin-dir`, `--no-extensions`, `--skills`, `--no-skills`, `--no-rules` |\n\n`packages/coding-agent/src/cli/flag-spec.ts` is the single source that renders `--help` and drives the parser, so the two cannot disagree.\n\n## How do I script a command safely?\n\nRun these steps against the pinned executable:\n\n1. Read `xcsh <COMMAND> --help` for the release you pinned.\n2. Write long flags rather than single-character aliases.\n3. Request `--result-file` or `--mode json` wherever the command supports it.\n4. Pass `--allow-path` once per additional directory; it accumulates rather than replacing.\n\nTreat `xcsh --help` and each subcommand's `--help` as the version-matched authority. Global flags\nmust precede or follow arguments exactly as that help permits; protocol modes reserve stdout for\nframed data. Before scripting a mutating command, pin the xcsh version, pass the context and\nresource identifiers explicitly, and exercise the read or validation form. Exit status is the\nautomation contract; terminal color and progress text are not.\n",
50
+ "en/reference-troubleshooting/cli-reference.mdx": "---\ntitle: \"CLI command and flag reference\"\ndescription: \"Look up every top-level xcsh command and every global flag a session accepts.\"\nsidebar:\n order: 1\n label: \"CLI reference\"\n---\n\nThe installed `xcsh <COMMAND> --help` output is the command-line interface (CLI) authority for its release. This page lists the command and flag names that release exposes so you can find one without starting a session.\n\n## Which top-level commands exist?\n\n| Area | Commands |\n| --- | --- |\n| Resources | `validate`, `diff`, `create`, `apply`, `update`, `get`, `export`, `delete` |\n| Runtime | `config`, `setup`, `sandbox`, `shell`, `ssh`, `stats`, `search` |\n| Files and code | `read`, `grep`, `jupyter` |\n| Extensibility | `agents`, `plugin`, `worker`, `manager` |\n| Interfaces | `chrome`, `chrome-host`, `office`, `herdr` |\n| Repository | `commit`, `grievances` |\n| Maintenance | `self-update` |\n\n`search` also answers to `q`. `update -f` names a resource manifest; executable checks and updates use `self-update`.\n\n`xcsh self-update --check` is read-only and reports the installation channel. Homebrew,\napt, npm, Bun, Windows installer, and direct MDM installations retain ownership:\nthe command prints their exact upgrade instruction or managed-install message and\nperforms no update. Only a standalone Unix executable with a valid adjacent\n`xcsh-install.json` receipt can replace itself. Unknown or conflicting provenance\nexits nonzero without changing files, and `--force` does not bypass this policy.\nThe standalone receipt uses schema v2 and records the canonical absolute executable\npath. Schema-v1 installations must run the documented installer once; they are not\nparsed or migrated by `self-update`. Executable and receipt replacement is one\nrollback-safe transaction.\n\n## Which global flags does a session accept?\n\nThese flags configure an agent launch. They precede the prompt and do not apply to a subcommand.\n\n| Group | Flags |\n| --- | --- |\n| Model | `--model`, `--smol`, `--slow`, `--plan`, `--provider`, `--models`, `--thinking`, `--list-models` |\n| Credentials and context | `--api-key`, `--context` |\n| Prompt | `--system-prompt`, `--append-system-prompt`, `--no-title` |\n| Mode | `--mode` (`text`, `json`, `rpc`, `acp`), `-p`/`--print` |\n| Session | `-c`/`--continue`, `-r`/`--resume`, `--fork`, `--session-dir`, `--no-session`, `--no-memories`, `--export` |\n| Filesystem | `--allow-home`, `--allow-path`, `--no-sandbox` |\n| Capabilities | `--tools`, `--no-tools`, `--no-lsp`, `--no-pty` |\n| Discovery | `-e`/`--extension`, `--hook`, `--plugin-dir`, `--no-extensions`, `--skills`, `--no-skills`, `--no-rules` |\n\n`packages/coding-agent/src/cli/flag-spec.ts` is the single source that renders `--help` and drives the parser, so the two cannot disagree.\n\n## How do I script a command safely?\n\nRun these steps against the pinned executable:\n\n1. Read `xcsh <COMMAND> --help` for the release you pinned.\n2. Write long flags rather than single-character aliases.\n3. Request `--result-file` or `--mode json` wherever the command supports it.\n4. Pass `--allow-path` once per additional directory; it accumulates rather than replacing.\n\nTreat `xcsh --help` and each subcommand's `--help` as the version-matched authority. Global flags\nmust precede or follow arguments exactly as that help permits; protocol modes reserve stdout for\nframed data. Before scripting a mutating command, pin the xcsh version, pass the context and\nresource identifiers explicitly, and exercise the read or validation form. Exit status is the\nautomation contract; terminal color and progress text are not.\n",
51
51
  "en/reference-troubleshooting/configuration-schema.mdx": "---\ntitle: \"Configuration schema\"\ndescription: \"Look up the settings namespaces xcsh validates, and the commands that report effective values.\"\nsidebar:\n order: 3\n label: \"Configuration schema\"\n---\n\n`packages/coding-agent/src/config/settings-schema.ts` defines every recognized settings key with its type, default, and validation. It evolves with the executable, so read the key namespaces here and the values from your own installation.\n\n## Which key namespaces exist?\n\n| Area | Namespaces |\n| --- | --- |\n| Appearance | `theme`, `statusLine`, `display`, `tui`, `terminal`, `images`, `media` |\n| Model and routing | `routing`, `retry`, `thinkingBudgets`, `providers`, `exa` |\n| Interaction | `startup`, `keybindings`, `completion`, `ask`, `stt`, `marketplace` |\n| Context and session | `context`, `contextPromotion`, `compaction`, `branchSummary`, `memories`, `ttsr`, `power` |\n| Editing | `edit`, `read`, `lsp`, `bashInterceptor`, `python` |\n| Tools | `tools`, `todo`, `find`, `grep`, `astGrep`, `astEdit`, `notebook`, `fetch`, `browser`, `web_search`, `calc`, `checkpoint`, `debug`, `inspect_image`, `generate_image`, `renderMermaid`, `bash`, `async` |\n| Tasks and capabilities | `task`, `tasks`, `skills`, `commands` |\n| Security | `secrets`, `sandbox`, `xcsh` |\n| Repository workflows | `commit`, `dev` |\n\nA key is `namespace.name`, as in `compaction.thresholdPercent` or `sandbox.allowRead`. Nested groups extend that form, as in `todo.reminders.max`.\n\n## How do I control session sleep prevention?\n\n`power.sleepPrevention` defaults to `idle`. Set it to `off`, `idle`, `display`, or `system`; each\nlevel is cumulative and applies only while an agent session is active. xcsh maps the setting to\nIOKit on macOS, login1 and ScreenSaver on Linux, and thread-affine execution state on Windows.\n\n## How do I inspect the effective schema-backed values?\n\n```bash\nxcsh config list --json\nxcsh config get <KEY>\n```\n\nUse `xcsh config set <KEY> <VALUE>` only for a key present in the installed schema. Reset one key with `xcsh config reset <KEY>` rather than copying defaults from another release.\n\n## Which source defines a setting?\n\nThe settings schema and its tests in the matching source release define type, default, and validation. `xcsh config list --json` reports the value after user, project, environment, and command-line precedence is applied. When the two disagree, the schema describes what is legal and the effective output describes what is active.\n\nUnknown keys and wrong value types are configuration errors, even when a nearby subsystem has a\nsimilarly named option. Consult the generated schema for the installed version, place the key under\nits documented namespace, and restart the process after editing. Use `/settings` to inspect\neffective interactive values. When diagnosing precedence, remove the highest-priority override and\nrelaunch rather than editing several layers at once.\n",
52
52
  "en/reference-troubleshooting/diagnostics.mdx": "---\ntitle: \"Run diagnostics\"\ndescription: \"Collect version, configuration, provider, context, and sandbox evidence without exposing secrets.\"\nsidebar:\n order: 4\n label: \"Run diagnostics\"\n---\n\nCollect the smallest evidence set that identifies the failing layer. Never print credentials or raw context files.\n\n## The shell cannot find xcsh\n\nRun `command -v xcsh` and `xcsh --version`. If the path belongs to an old installation channel, remove that channel and reinstall once through the intended channel.\n\n## A model is unavailable or authentication fails\n\nRun `xcsh --list-models <PROVIDER>`. If no models appear, verify the relevant credential is present without echoing it. Retry with a provider-qualified `--model` name.\n\nFor Fable, `credits_required` means the authenticated Anthropic account is not entitled or funded\nfor that model; xcsh reports it once without retrying. Check Claude subscription access or API\nbilling for the credential in use. An obsolete-client error also does not retry: upgrade xcsh so\nits Claude Code compatibility header matches the current client, then try again.\n\n## A context or resource command fails\n\nConfirm `/context status` and the explicit namespace. Run `validate` to separate local manifest errors from live application programming interface (API) errors, then retry a read-only `get` or `diff`.\n\n## A tool or extension fails during startup\n\nStart from the smallest surface, then widen it:\n\n1. Run with `--no-extensions --no-rules`, adding `--no-pty` if the terminal itself is suspect.\n2. Re-enable one subsystem, then repeat the failing command.\n3. Check optional dependencies with `xcsh setup <COMPONENT> --check --json`.\n4. Check plugins with `xcsh plugin doctor`.\n",
53
53
  "en/reference-troubleshooting/index.mdx": "---\ntitle: \"Reference and troubleshooting\"\ndescription: \"Diagnose installations, providers, contexts, and tools, then consult current command and configuration references.\"\nsidebar:\n order: 0\n label: \"Reference\"\n---\n\nBegin with the observed symptom and isolate one layer at a time.\n\n## Where do I look?\n\n- [Diagnostics](/xcsh/en/reference-troubleshooting/diagnostics/) for installation, provider, context, and tool symptoms.\n- [command-line interface (CLI) reference](/xcsh/en/reference-troubleshooting/cli-reference/) for current command shapes.\n- [Slash commands and hotkeys](/xcsh/en/reference-troubleshooting/slash-keybindings/) for interactive discovery.\n- [Configuration schema](/xcsh/en/reference-troubleshooting/configuration-schema/) for supported settings.\n\nTerms are defined where they are used; there is no separate glossary.\n",
@@ -259,6 +259,10 @@ function boundedSnippet(markdown: string, query: string): string {
259
259
  return `${prefix}${body.slice(start, start + 598 - prefix.length - suffix.length)}${suffix}`;
260
260
  }
261
261
 
262
+ function lexicalDocumentationQuery(query: string): string {
263
+ return query.replace(/^\s*(?:what|who)\s+(?:is|are)\s+/i, "").trim() || query;
264
+ }
265
+
262
266
  export function createEmbeddedDocumentationRepository(
263
267
  assets: EmbeddedDocumentationAssets,
264
268
  options: EmbeddedDocumentationRepositoryOptions = {},
@@ -297,7 +301,7 @@ export function createEmbeddedDocumentationRepository(
297
301
  },
298
302
  search: async (query, source, limit): Promise<readonly DocumentationSearchResult[]> => {
299
303
  const current = await state();
300
- const results = await current.store.searchLex(query, { limit, collection: source });
304
+ const results = await current.store.searchLex(lexicalDocumentationQuery(query), { limit, collection: source });
301
305
  const rows: DocumentationSearchResult[] = [];
302
306
  const lookup = current.database.query(
303
307
  "SELECT source, stable_path, title, original_url, markdown FROM documentation_documents WHERE source = ? AND stable_path = ?",
@@ -1,6 +1,6 @@
1
1
  import type { InternalResource, InternalUrl } from "./types";
2
2
 
3
- export const DOCUMENTATION_SOURCES = ["docs-cloud-f5-com", "my-f5-com"] as const;
3
+ export const DOCUMENTATION_SOURCES = ["docs-cloud-f5-com", "my-f5-com", "www-f5-com"] as const;
4
4
  export type DocumentationSource = (typeof DOCUMENTATION_SOURCES)[number];
5
5
 
6
6
  export interface DocumentationProvenance {
@@ -68,7 +68,13 @@ const DOCUMENT_PROVENANCE_KEYS = [
68
68
  const SOURCE_ROOT_URLS: Readonly<Record<DocumentationSource, string>> = {
69
69
  "docs-cloud-f5-com": "https://docs.cloud.f5.com/docs-v2",
70
70
  "my-f5-com": "https://my.f5.com/manage/s",
71
+ "www-f5-com": "https://www.f5.com/products/distributed-cloud-services",
71
72
  };
73
+ const MARKETING_SOLUTION_URLS = new Set([
74
+ "https://www.f5.com/solutions/use-cases/hybrid-multicloud-application-delivery",
75
+ "https://www.f5.com/solutions/use-cases/multi-cloud-networking",
76
+ "https://www.f5.com/solutions/web-app-and-api-protection",
77
+ ]);
72
78
 
73
79
  export interface DocumentationReleaseAssetPin {
74
80
  readonly sha256: string;
@@ -182,7 +188,11 @@ function validateTimestamp(value: unknown, field: string): string {
182
188
  function validateOriginalUrl(value: unknown, source: DocumentationSource, field: string): string {
183
189
  const result = string(value, field);
184
190
  const root = SOURCE_ROOT_URLS[source];
185
- if (result !== root && !result.startsWith(`${root}/`) && !result.startsWith(`${root}?`)) {
191
+ const allowed =
192
+ source === "www-f5-com"
193
+ ? result === root || result.startsWith(`${root}/`) || MARKETING_SOLUTION_URLS.has(result)
194
+ : result === root || result.startsWith(`${root}/`) || result.startsWith(`${root}?`);
195
+ if (!allowed) {
186
196
  throw new Error(`${field} is outside the declared source root`);
187
197
  }
188
198
  return result;
@@ -598,6 +608,12 @@ export async function verifyDocumentationRelease(
598
608
  const markdown = entry.data.toString("utf8");
599
609
  const parsed = splitDocument(markdown);
600
610
  const originalUrl = validateOriginalUrl(item.url, source, "manifest document URL");
611
+ if (
612
+ source === "www-f5-com" &&
613
+ archiveMemberPath !== `content/www-f5-com${new URL(originalUrl).pathname}/index.md`
614
+ ) {
615
+ throw new Error(`marketing document path does not match its reviewed URL: ${archiveMemberPath}`);
616
+ }
601
617
  if (parsed.metadata.sourceId !== source || parsed.metadata.url !== originalUrl)
602
618
  throw new Error(`manifest document frontmatter mismatch: ${archiveMemberPath}`);
603
619
  const bodySha256 = string(item.body_sha256, "manifest document body hash");
@@ -620,6 +636,9 @@ export async function verifyDocumentationRelease(
620
636
  };
621
637
  });
622
638
 
639
+ const marketingDocumentPaths = new Set(
640
+ documents.filter(document => document.source === "www-f5-com").map(document => document.stablePath),
641
+ );
623
642
  const assets = manifest.assets.map((value, position): VerifiedDocumentationAsset => {
624
643
  const item = object(value, `manifest asset ${position}`);
625
644
  exactKeys(item, MANIFEST_ASSET_KEYS, `manifest asset ${position}`);
@@ -631,6 +650,9 @@ export async function verifyDocumentationRelease(
631
650
  const source = archiveMemberPath.split("/")[1] as DocumentationSource;
632
651
  if (!DOCUMENTATION_SOURCES.includes(source)) throw new Error(`unknown manifest asset source: ${source}`);
633
652
  const parsed = stableAssetPath(archiveMemberPath, source);
653
+ if (source === "www-f5-com" && !marketingDocumentPaths.has(parsed.stablePath)) {
654
+ throw new Error(`marketing asset is not attached to a reviewed document: ${archiveMemberPath}`);
655
+ }
634
656
  const digest = string(item.sha256, "manifest asset hash");
635
657
  if (!SHA256.test(digest) || !parsed.filename.startsWith(`${digest}.`)) {
636
658
  throw new Error(`manifest asset digest filename mismatch: ${archiveMemberPath}`);
@@ -843,6 +865,11 @@ export async function buildDocumentationIndex(
843
865
  pattern: "**/*.md",
844
866
  context: { "/": "MyF5 support and knowledge-base documentation" },
845
867
  },
868
+ "www-f5-com": {
869
+ path: path.join(documentsRoot, "www-f5-com"),
870
+ pattern: "**/*.md",
871
+ context: { "/": "F5 Distributed Cloud product and solution overviews" },
872
+ },
846
873
  },
847
874
  },
848
875
  });
@@ -1,5 +1,5 @@
1
1
  export type KnowledgeRoute = "api" | "documentation" | "direct-uri" | "none";
2
- export type DocumentationKnowledgeSource = "docs-cloud-f5-com" | "my-f5-com";
2
+ export type DocumentationKnowledgeSource = "docs-cloud-f5-com" | "my-f5-com" | "www-f5-com";
3
3
 
4
4
  export interface KnowledgeClassifierResource {
5
5
  readonly name: string;
@@ -46,7 +46,11 @@ const ANAPHORIC = /\b(?:its|it|that|this|those|them|the same)\b/i;
46
46
  const API_METADATA =
47
47
  /\b(?:api|endpoint|operation\s*id|api\s+path|http\s+method|method|payload|request\s+body|required\s+fields?|enum|allowed\s+values?|constraints?|limits?|maximum|max(?:imum)?|minimum|min(?:imum)?|how\s+many|create|creates|creating|get|gets|list|lists|update|updates|replace|replaces|delete|deletes|clone|import)\b/i;
48
48
  const DOCUMENTATION_INTENT =
49
- /\b(?:documentation|docs?|guide|tutorial|how\s+(?:do|can|to)|configure|configuration|set\s*up|troubleshoot|procedure|instructions?)\b/i;
49
+ /\b(?:documentation|docs?|guide|tutorial|how\s+(?:do|can|to)|configure|configuration|set\s*up|troubleshoot|procedure|instructions?|what\s+(?:is|are)|overview|product|solution|capabilities|benefits)\b/i;
50
+ const CONFIGURATION_INTENT = /\b(?:configure|configuration|set\s*up|procedure|instructions?|how\s+(?:do|can|to))\b/i;
51
+ const SUPPORT_INTENT = /\b(?:troubleshoot|support|knowledge[- ]base|error|failure|issue|K[0-9]{6,})\b/i;
52
+ const MARKETING_TOPIC =
53
+ /\b(?:client[- ]side defense|distributed cloud|web (?:app|application) and api protection|multi[- ]cloud networking|dns load balancer|bot defense|api security|app connect|appstack|content delivery network|cdn|mobile app shield|synthetic monitoring|web app scanning)\b/i;
50
54
  const EXCLUDED_API_INTENT = /\b(?:pricing|price|quote|licen[cs]ing|sales)\b/i;
51
55
  const DIRECT_URI = /\bxcsh:\/\/(?:api-catalog|api-spec|documentation)\/[^\s)>\]}]*/i;
52
56
 
@@ -130,7 +134,9 @@ function direct(prompt: string): KnowledgeClassification | null {
130
134
  }
131
135
  if (parsed.hostname === "documentation") {
132
136
  const source = parsed.pathname.split("/").filter(Boolean)[0];
133
- if (source === "docs-cloud-f5-com" || source === "my-f5-com") Object.assign(constraints, { source });
137
+ if (source === "docs-cloud-f5-com" || source === "my-f5-com" || source === "www-f5-com") {
138
+ Object.assign(constraints, { source });
139
+ }
134
140
  }
135
141
  return { route: "direct-uri", confidence: 1, directUri, constraints, query: EMPTY_QUERY };
136
142
  } catch {
@@ -191,9 +197,17 @@ export function classifyKnowledgeRequest(prompt: string, options: KnowledgeClass
191
197
  if (
192
198
  !thirdPartyOnly &&
193
199
  (DOCUMENTATION_INTENT.test(prompt) || (ANAPHORIC.test(prompt) && previousDocumentation)) &&
194
- (F5_SCOPE.test(prompt) || /\b(?:documentation|docs?)\b/i.test(prompt) || previousDocumentation)
200
+ (F5_SCOPE.test(prompt) ||
201
+ /\b(?:documentation|docs?)\b/i.test(prompt) ||
202
+ MARKETING_TOPIC.test(prompt) ||
203
+ previousDocumentation)
195
204
  ) {
196
- const source = options.documentationSource ?? previousDocumentation?.source;
205
+ const inferredSource = SUPPORT_INTENT.test(prompt)
206
+ ? "my-f5-com"
207
+ : CONFIGURATION_INTENT.test(prompt)
208
+ ? "docs-cloud-f5-com"
209
+ : "www-f5-com";
210
+ const source = options.documentationSource ?? previousDocumentation?.source ?? inferredSource;
197
211
  const subject = documentationSubject(prompt);
198
212
  return {
199
213
  route: "documentation",