Docs Site
The public WendyOS documentation site is built with Fumadocs and Next.js, then published as a static export to https://docs.wendy.dev.
Docs Site
The public WendyOS documentation site is built with Fumadocs and Next.js, then
published as a static export to https://docs.wendy.dev.
URLs
| Purpose | URL |
|---|---|
| Latest stable docs | https://docs.wendy.dev/latest/ |
| Latest nightly docs | https://docs.wendy.dev/latest-nightly/ |
| Specific stable release | https://docs.wendy.dev/release-<version>/ |
| Specific nightly release | https://docs.wendy.dev/release-nightly-<version>/ |
| Branch preview | https://docs.wendy.dev/branch-<branch>-<sha>/ |
| Agent docs index for the latest stable docs | https://docs.wendy.dev/llms.txt |
Source Layout
The Fumadocs app is reached through docs/, which is a repository-root symlink
to go/internal/cli/assets/docs. Top-level docs content lives as MDX and
meta.json files in that tree. Existing lower-level Markdown reference files
are still read from the same tree, but the prep script publishes them under the
advanced/ section at build time.
docs/
app/ Next.js app router routes, layout, and search
components/ MDX components, search dialog, and providers
guides/ Top-level guides and tutorials
installation/ Top-level setup guides
lib/ Fumadocs source loader and shared layout config
scripts/ Content preparation for Fumadocs
next.config.mjs
package.jsonGenerated build output is ignored by git: content/, public/, .source/,
.next/, out/, and export/.
Local Development
cd docs
npm ci
npm run devThe dev server starts at http://localhost:3000/.
When editing source Markdown or MDX files, rerun the content prep script to refresh generated Fumadocs content:
cd docs
node scripts/prepare-content.mjsLocal Build
The deployed site uses a path prefix. Set NEXT_PUBLIC_BASE_PATH when testing a
prefixed build:
cd docs
NEXT_PUBLIC_BASE_PATH=/branch-local npm run buildThe static export is written to docs/out/.
CI And Deploy
The .github/workflows/fumadocs.yml workflow runs when docs,
docs/**, go/internal/cli/assets/docs/**, or the workflow file changes.
| Trigger | Behavior |
|---|---|
main branch push | Builds and deploys a branch preview |
Pull request to main from this repository | Builds and deploys a branch preview, then posts or updates a sticky PR comment with the preview URL. Fork PRs do not receive preview comments. |
| Published stable release | Deploys release-<version>/, updates latest/, and publishes the root llms.txt and llms-full.txt |
| Published prerelease/nightly | Deploys release-nightly-<version>/ and updates latest-nightly/ |
| Manual dispatch (no inputs) | Builds a branch-style preview artifact without deploying |
Manual dispatch with release_tag input | Deploys a release, identical to a published-release trigger. The release_prerelease input selects the target: false (default) deploys release-<version>/ and updates latest/; true deploys release-nightly-<version>/ and updates latest-nightly/. The dispatch ref must match release_tag (dispatch with --ref "<release_tag>"), otherwise the deploy fails fast so docs built from one ref are never published under a different release path. |
Preview URLs are posted to same-repository PR comments and are visible to anyone who can read the PR. This is intentional; deploy paths are public preview paths and should not include sensitive information.
The deploy job authenticates to GCP with Workload Identity Federation and syncs
static files to gs://wendy-docs-public/<deploy-path>. Static exports include
SHA-256 manifests that are verified before each deploy path is synced.
Release deploys attempt to enable bucket object versioning before updating
latest/ or latest-nightly/ so alias overwrites remain recoverable. If the
deploy identity lacks bucket-update permission, the deploy verifies the current
state instead: it aborts only when versioning is confirmed disabled (an
overwrite would be unrecoverable), and continues with a warning when versioning
is already enabled out-of-band or cannot be read.
Required GitHub environment variables:
| Variable | Description |
|---|---|
GCP_WORKLOAD_IDENTITY_PROVIDER | Workload Identity provider resource name |
GCP_SERVICE_ACCOUNT | Deploy service account email |
GCP_PROJECT_ID | GCP project ID |
Hosting
Static files are served from the public wendy-docs-public Cloud Storage bucket
through the global external HTTP(S) load balancer for docs.wendy.dev. The load
balancer terminates HTTPS and adds security response headers for the public
docs host.
Branch-preview objects under branch-* are cleaned up by CI after 30 days.
Vanity redirects
Short marketing paths are served as static redirect pages uploaded to the
bucket root by the Deploy vanity redirects step in
.github/workflows/fumadocs.yml (main-branch pushes and release deploys only):
| Path | Target |
|---|---|
/pi | /latest/installation/wendyos-raspberry-pi-5/ |
/thor | /latest/installation/wendyos-nvidia-jetson-agx-thor/ |
/jetson, /jetson-orin, /jetson-orin-nano | /latest/installation/wendyos-nvidia-jetson-orin-nano/ |
Add new entries to the REDIRECTS map in that workflow step. Slugs must not
collide with deploy path prefixes (latest, latest-nightly, release-*,
branch-*).
Security headers
The load balancer adds these headers to every docs.wendy.dev response. They
are custom response headers on the backend bucket wendy-docs-backend, which
the URL map wendy-docs-url-map routes docs.wendy.dev to, in the GCP project
from vars.GCP_PROJECT_ID. No file in this repository manages them.
install.wendy.dev and templates.wendy.dev share the load balancer but use
other backend buckets without these headers.
| Header | Value |
|---|---|
X-Content-Type-Options | nosniff |
X-Frame-Options | DENY |
Referrer-Policy | strict-origin-when-cross-origin |
Permissions-Policy | camera=(), microphone=(), geolocation=() |
Content-Security-Policy | The policy below |
default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; frame-src https://www.youtube.com https://www.youtube-nocookie.com; img-src 'self' data: blob: https://www.googletagmanager.com https://*.google-analytics.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; connect-src 'self' https://www.googletagmanager.com https://*.google-analytics.com https://*.google.com; worker-src 'self' blob:What the policy means for docs changes:
- Images must come from the docs site itself. Commit them to the docs tree
instead of linking to another host. The
YouTubeVideocomponent uses local thumbnails inimages/youtube/for this reason. - Iframes can only embed YouTube.
- The Google Analytics hosts follow Google's list for GA4 without Ads features.
Until 2026-09-27 the policy blocked
gtag.js, so docs page views before that date were not recorded. Turning on Google Signals or linking Google Ads needs more hosts.
Read the current headers:
gcloud compute backend-buckets describe wendy-docs-backend \
--project=<GCP_PROJECT_ID> --format='yaml(customResponseHeaders)'To change a header, pass the complete list.
gcloud compute backend-buckets update --custom-response-header replaces every
custom header, so any header you leave out is removed:
gcloud compute backend-buckets update wendy-docs-backend --project=<GCP_PROJECT_ID> \
--custom-response-header="X-Content-Type-Options: nosniff" \
--custom-response-header="X-Frame-Options: DENY" \
--custom-response-header="Referrer-Policy: strict-origin-when-cross-origin" \
--custom-response-header="Permissions-Policy: camera=(), microphone=(), geolocation=()" \
--custom-response-header="Content-Security-Policy: <complete policy>"Changes reach responses within a few minutes, including responses the CDN has
already cached, so no cache invalidation is needed. Verify with
curl -sI https://docs.wendy.dev/latest/, then open a docs page and confirm
the browser console shows no Content Security Policy errors.
Agent Docs (llms.txt)
Each deploy path also publishes Markdown for AI agents. The "View raw Markdown" and "Agent docs index" page actions link to these files.
| File | Contents |
|---|---|
<deploy-path>/llms.txt | Index in the llms.txt format: a summary, the docs pages, and the generated CLI and detailed reference under ## Optional |
<deploy-path>/llms-full.txt | The source of every page in one file |
<deploy-path>/markdown/<page>.md | The source of one page |
scripts/publish-markdown.mjs writes these files during content preparation.
Stable release deploys also copy latest/llms.txt and latest/llms-full.txt
to the site root, where agents look first, in the Publish root llms.txt step
of .github/workflows/fumadocs.yml. Nightly releases and branch previews leave
the root copies unchanged.
Release Notifications
The release workflow adds docs links to Discord notifications:
| Release type | Links |
|---|---|
| Stable | release-<version>/ and latest/ |
| Nightly | release-nightly-<version>/ and latest-nightly/ |
Validation
Run these before opening or updating a PR that changes the docs app:
cd docs
npm run types:check
npm run buildDebugging the wendy-agent
This page covers debugging the agent daemon itself — its startup, gRPC server, container management, and internal subsystems. For debugging apps running on a device (attaching a de
Install Script Hosting
The public install one-liners are served from Google Cloud, not GitHub Pages: