Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,18 @@ After documenting any new functionality, before declaring the work done:
5. If the functionality has dashboard settings, verify `fern/products/dashboard/pages/` covers them — usually folded into the most relevant existing page, not a new page.
6. Verify every link you wrote — see *Link checking* above for URL construction.

## Agent instruction pages

`fern/products/home/pages/fern-instructions/` holds hidden pages written for coding agents. They're served at `/learn/home/fern-instructions/<topic>.md`, and they're the content behind the proposed `fern instructions <topic>` CLI command. Each page condenses the canonical pages listed in its `## Reference` section. The pages are hidden from the sidebar, search and `llms.txt`, so readers won't notice when they go stale. Keep them in sync in the same PR as the change that affects them.

- When you change a canonical page, find the instruction pages that cite it and update them too. Search for the page's `/learn/...` URL path, for example `grep -rl "docs/preview-publish/publishing-your-docs" fern/products/home/pages/fern-instructions/`.
- When you document a CLI command, flag or behavior change, also search the instruction pages for the command name, for example `fern generate --guest`, `fern claim` or `fern whoami`. Some pages describe commands without linking a canonical page.
- Edit only the steps, rules and checks that changed. Keep each page short and scoped to one task.
- To add a topic, add the page with `hidden: true` in `fern/products/home/home.yml` and add a row to the index in `topics.mdx`. Don't link instruction pages from visible pages.
- The index page, `topics.mdx` (served at `/learn/home/fern-instructions.md`), is a contract with the Fern CLI and with `agents.page-directive` in `docs.yml`. Don't move it, change its slug, or change the format of its topic tables unless the CLI in `fern-api/fern` is updated too.
- The proposed CLI builds each topic's URL from its name, for example `fern instructions docs publish domain` fetches `/learn/home/fern-instructions/docs/publish/domain.md`, so released CLI versions depend on those paths. If you move or rename an instruction page, add a redirect in `docs.yml` from the old path to the new one. Redirects also apply to the `.md` URL, and a `:slug*` wildcard covers a moved folder.
- If you aren't sure whether a change affects an instruction page, say so in the PR description.

## Generated files

Automation owns some paths in this repo. Never write to them by hand, and never delete or reformat what automation put there: the next sync reverts the edit, and a hand-written change collides with the automated pull request that maintains the file.
Expand Down
2 changes: 1 addition & 1 deletion fern/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ js:
strategy: afterInteractive

agents:
page-directive: "For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt."
page-directive: "For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. For task-scoped instructions for coding agents working in a Fern project, see https://buildwithfern.com/learn/home/fern-instructions.md."

analytics:
# posthog:
Expand Down
128 changes: 127 additions & 1 deletion fern/products/home/home.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,130 @@ navigation:
path: ./pages/welcome.mdx
- page: Get started with a coding agent
path: ./pages/agent-onboarding.mdx
hidden: true
hidden: true
- page: Fern instructions
path: ./pages/fern-instructions/topics.mdx
hidden: true
- page: How a Fern project works
path: ./pages/fern-instructions/overview.mdx
hidden: true
- page: Start a new Fern project
path: ./pages/fern-instructions/new-site.mdx
hidden: true
- page: Troubleshoot Fern errors
path: ./pages/fern-instructions/troubleshoot.mdx
hidden: true
- page: Write Fern docs pages
path: ./pages/fern-instructions/docs/write.mdx
hidden: true
- page: Use Fern docs components
path: ./pages/fern-instructions/docs/write/components.mdx
hidden: true
- page: Configure a Fern docs site
path: ./pages/fern-instructions/docs/configure.mdx
hidden: true
- page: Configure Fern docs navigation
path: ./pages/fern-instructions/docs/configure/navigation.mdx
hidden: true
- page: Customize a Fern docs site
path: ./pages/fern-instructions/docs/configure/customization.mdx
hidden: true
- page: Configure SEO for Fern docs
path: ./pages/fern-instructions/docs/configure/seo.mdx
hidden: true
- page: Localize Fern docs
path: ./pages/fern-instructions/docs/configure/localization.mdx
hidden: true
- page: Generate an API Reference in Fern docs
path: ./pages/fern-instructions/docs/api-reference.mdx
hidden: true
- page: Preview and publish Fern docs
path: ./pages/fern-instructions/docs/publish.mdx
hidden: true
- page: Set up a custom domain for Fern docs
path: ./pages/fern-instructions/docs/publish/domain.mdx
hidden: true
- page: Restrict access to Fern docs
path: ./pages/fern-instructions/docs/access.mdx
hidden: true
- page: Configure AI features in Fern docs
path: ./pages/fern-instructions/docs/ai.mdx
hidden: true
- page: Add analytics to Fern docs
path: ./pages/fern-instructions/docs/analytics.mdx
hidden: true
- page: Prepare an API spec for Fern
path: ./pages/fern-instructions/spec.mdx
hidden: true
- page: Use Fern OpenAPI extensions
path: ./pages/fern-instructions/spec/extensions.mdx
hidden: true
- page: Change a spec you can't edit
path: ./pages/fern-instructions/spec/overrides.mdx
hidden: true
- page: Define auth and servers in an API spec
path: ./pages/fern-instructions/spec/auth.mdx
hidden: true
- page: Keep an API spec in sync
path: ./pages/fern-instructions/spec/sync.mdx
hidden: true
- page: Use AsyncAPI, gRPC, OpenRPC, or a Fern Definition
path: ./pages/fern-instructions/spec/formats.mdx
hidden: true
- page: Generate SDKs with Fern
path: ./pages/fern-instructions/sdks.mdx
hidden: true
- page: Generate a TypeScript SDK with Fern
path: ./pages/fern-instructions/sdks/typescript.mdx
hidden: true
- page: Generate a Python SDK with Fern
path: ./pages/fern-instructions/sdks/python.mdx
hidden: true
- page: Generate a Go SDK with Fern
path: ./pages/fern-instructions/sdks/go.mdx
hidden: true
- page: Generate a Java SDK with Fern
path: ./pages/fern-instructions/sdks/java.mdx
hidden: true
- page: Generate a C# SDK with Fern
path: ./pages/fern-instructions/sdks/csharp.mdx
hidden: true
- page: Generate a PHP SDK with Fern
path: ./pages/fern-instructions/sdks/php.mdx
hidden: true
- page: Generate a Ruby SDK with Fern
path: ./pages/fern-instructions/sdks/ruby.mdx
hidden: true
- page: Generate a Swift SDK with Fern
path: ./pages/fern-instructions/sdks/swift.mdx
hidden: true
- page: Generate a Rust SDK with Fern
path: ./pages/fern-instructions/sdks/rust.mdx
hidden: true
- page: Publish Fern SDKs
path: ./pages/fern-instructions/sdks/publish.mdx
hidden: true
- page: Keep custom code in Fern SDKs
path: ./pages/fern-instructions/sdks/custom-code.mdx
hidden: true
- page: Configure Fern SDK features
path: ./pages/fern-instructions/sdks/features.mdx
hidden: true
- page: Generate and test Fern SDKs locally
path: ./pages/fern-instructions/sdks/local.mdx
hidden: true
- page: Migrate Fern SDK configuration
path: ./pages/fern-instructions/sdks/migrate.mdx
hidden: true
- page: Automate Fern in CI
path: ./pages/fern-instructions/automate.mdx
hidden: true
- page: Manage a Fern organization
path: ./pages/fern-instructions/access-team.mdx
hidden: true
- page: Migrate docs to Fern
path: ./pages/fern-instructions/migrate.mdx
hidden: true
- page: Generate a CLI from an API definition
path: ./pages/fern-instructions/cli-generator.mdx
hidden: true
29 changes: 29 additions & 0 deletions fern/products/home/pages/fern-instructions/access-team.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Manage a Fern organization
slug: fern-instructions/access/team
description: Manage Fern Dashboard members and permissions, organization tokens, SSO, custom domains, and the connected GitHub repository.
---

Use this for organization-level access, not for gating docs readers (see `docs access`).

## Workflow

1. Check the identity in use with `fern whoami`.
2. Members and roles are managed in the [Fern Dashboard](https://dashboard.buildwithfern.com). The user does this in the browser.
3. Tokens for CI: `fern token` creates one. `fern org token list`, `fern org token create` and `fern org token revoke` manage them.
4. Organization settings: `fern org get` shows them, and `fern org set cli-version` / `fern org unset cli-version` control the CLI version policy.
5. Dashboard settings cover SSO, API keys, the connected GitHub repo, custom domains, password protection and PDF export.

## Rules

- Only organization admins can change members, tokens and settings. If a command fails with a permission error, the user needs an admin.
- Revoke tokens that leak or are no longer used.

## Reference

- [Dashboard overview](https://buildwithfern.com/learn/dashboard/getting-started/overview.md)
- [Permissions](https://buildwithfern.com/learn/dashboard/configuration/permissions.md)
- [API keys](https://buildwithfern.com/learn/dashboard/configuration/api-keys.md)
- [SSO](https://buildwithfern.com/learn/dashboard/configuration/sso.md)
- [GitHub repository](https://buildwithfern.com/learn/dashboard/configuration/github-repo.md)
- [General CLI commands](https://buildwithfern.com/learn/cli-api-reference/cli-reference/general-commands.md)
35 changes: 35 additions & 0 deletions fern/products/home/pages/fern-instructions/automate.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: Automate Fern in CI
slug: fern-instructions/automate
description: Run fern check on pull requests, publish docs previews per pull request, publish docs on merge, and release SDKs from CI with FERN_TOKEN.
---

Use this to set up or fix a CI workflow that runs the Fern CLI.

## Workflow

1. Create an organization token with `fern token` and store it as a CI secret named `FERN_TOKEN`. Never print or commit it.
2. Pin a concrete CLI `version` in `fern.config.json` so CI and local runs match. Install the CLI in CI with `fern-api/setup-fern-cli@v1` (GitHub Actions) or `npm install -g fern-api`.
3. Add the jobs the user needs:
- Pull requests: `fern check`.
- Docs preview per pull request: `fern generate --docs --preview --id <branch> --no-prompt`, then post the printed URL (`Published docs to <url>`, on stderr) as a comment.
- Docs on merge to the default branch: `fern generate --docs --no-prompt`.
- SDK release: `fern generate --target <language> --version <version> --force` (or `--group` for `generators.yml`).
4. Skip secret-dependent jobs on fork and Dependabot pull requests, which don't receive secrets.
5. To keep the spec current, add the `fern-api/sync-openapi` action. See `spec sync`.

## Rules

- Pass `--no-prompt` or `--force` to anything that can prompt. Prompts fail immediately when stdin isn't a TTY or `CI` is set.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <FernStyles.Acronyms> reported by reviewdog 🐶
'TTY' has no definition.

- Don't use `fern login` or `--guest` in CI. Use `FERN_TOKEN`.
- Run the command from the folder that contains `fern/`.

## Verify

- `fern whoami` in a CI step reports an organization token. The workflow passes on a test pull request and posts a working preview link.

## Reference

- [Publish your docs](https://buildwithfern.com/learn/docs/preview-publish/publishing-your-docs.md)
- [Preview changes](https://buildwithfern.com/learn/docs/preview-publish/preview-changes.md)
- [Sync your OpenAPI spec](https://buildwithfern.com/learn/api-definitions/openapi/sync-your-open-api-specification.md)
28 changes: 28 additions & 0 deletions fern/products/home/pages/fern-instructions/cli-generator.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: Generate a CLI from an API definition
slug: fern-instructions/cli-generator
description: Generate a command-line tool for an API with Fern, configure commands and auth, and publish it.
---

Use this when the user wants a CLI for their API, not to use the Fern CLI itself.

## Workflow

1. Follow the CLI generator quickstart to add the generator to the project.
2. Configure commands, auth and output from the configuration, authentication and customization pages. Add custom commands where the generated ones aren't enough.
3. Generate locally to try it, then set up publishing.

## Rules

- Command names come from the spec. Fix them there or with the generator's OpenAPI extensions.
- Look up configuration keys on the CLI generator pages. Don't reuse SDK keys.

## Reference

- [Overview](https://buildwithfern.com/learn/cli-generator/get-started/overview.md)
- [Quickstart](https://buildwithfern.com/learn/cli-generator/get-started/quickstart.md)
- [Configuration](https://buildwithfern.com/learn/cli-generator/get-started/configuration.md)
- [Authentication](https://buildwithfern.com/learn/cli-generator/get-started/authentication.md)
- [Custom commands](https://buildwithfern.com/learn/cli-generator/get-started/custom-commands.md)
- [Local generation](https://buildwithfern.com/learn/cli-generator/get-started/local-generation.md)
- [Publishing](https://buildwithfern.com/learn/cli-generator/get-started/publishing.md)
41 changes: 41 additions & 0 deletions fern/products/home/pages/fern-instructions/docs/access.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: Restrict access to Fern docs
slug: fern-instructions/docs/access
description: Gate Fern docs with a password, SSO, JWT, or OAuth, show content by role with RBAC, and inject readers' API keys into the API Explorer.
---

Use this to make some or all of a site private.
Comment thread
nerminamiller-postman marked this conversation as resolved.
Resolved

## Pick a method

| Need | Method |
|---|---|
| Quick gate with a shared password, no per-user accounts | Password protection (several passwords can map to roles) |
| Internal docs behind the company's login (Okta, Google Workspace and others) | SSO |
| Use the product's own login and control the flow yourself | JWT |
| Use the product's own login, with Fern running the flow through the OAuth provider | OAuth |

JWT, OAuth and SSO set a `fern_token` cookie that tells Fern who the reader is and which roles they have. Add RBAC to show different pages, sections or content to different roles, and API key injection to pre-fill the reader's key in the API Explorer.

## Workflow

1. Confirm the method with the user. Most methods need setup by Fern or values only the user has, such as an identity provider, a signing secret or OAuth client credentials. Don't invent them.
2. Follow the setup page for that method.
3. For RBAC, define roles in `docs.yml` and restrict navigation entries or page content to them, as described on the RBAC page.
4. Preview with `fern docs dev`. It includes a role selector and password login for sites that use them.

## Rules

- Never commit secrets such as JWT signing keys to the repo.
- Hiding a page (`hidden: true`) doesn't protect it. Anyone with the URL can open it. Use one of the methods above for content that must stay private.

## Verify

- Signed out, protected pages redirect to login or ask for the password. Signed in with each role, the reader sees exactly that role's content.

## Reference

- [Authentication overview](https://buildwithfern.com/learn/docs/authentication/overview.md)
- [Password protection](https://buildwithfern.com/learn/docs/authentication/setup/password-protection.md), [SSO](https://buildwithfern.com/learn/docs/authentication/setup/sso.md), [JWT](https://buildwithfern.com/learn/docs/authentication/setup/jwt.md), [OAuth](https://buildwithfern.com/learn/docs/authentication/setup/oauth.md)
- [RBAC](https://buildwithfern.com/learn/docs/authentication/features/rbac.md)
- [API key injection](https://buildwithfern.com/learn/docs/authentication/features/api-key-injection.md)
44 changes: 44 additions & 0 deletions fern/products/home/pages/fern-instructions/docs/ai.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: Configure AI features in Fern docs
slug: fern-instructions/docs/ai
description: Control llms.txt, Markdown access, agent directives, Ask Fern, the docs MCP server, and hosted agent skills on a Fern site.
---

Use this to change what AI agents and the site's AI assistant see.

## What every Fern site serves

- `/llms.txt`: an index of pages, each with a `.md` link.
- `<page URL>.md`: any page as Markdown. Agents should fetch this rather than HTML.
- `/_mcp/server`: an MCP server with `searchDocs` and `fetchPage` tools. For example, Fern's own docs: `https://buildwithfern.com/learn/_mcp/server`.

## Workflow

1. Agent-facing settings go under `agents` in `docs.yml`:
- `agents.page-directive`: the instruction added to the top of every `.md` page.
- `agents.page-description-source`: where page descriptions in `llms.txt` come from.
- `agents.llms-txt` and `agents.robots-txt`: control those files.
2. Content for one audience only: wrap it in `<llms-only>` (shown to agents in `.md`, hidden on the site) or `<llms-ignore>` (shown on the site, left out of `.md`).
3. Ask Fern, the site's AI chat, is configured under `ai-search`: `datasources` (extra sites to index), `system-prompt`, `disclaimer`, `mask-pii`. Add guidance and content sources from the Dashboard or the Ask Fern API.
4. Run `fern docs dev` and open a page's `.md` URL to check the output.

## Rules

- `<llms-only>` content is also hidden from Ask Fern. Don't put content there that Ask Fern needs to answer from.
- `hidden: true` and `noindex: true` pages are left out of `llms.txt`, but their `.md` URL still works.
- Keep the page directive short. It's prepended to every page.

## Verify

- `<site>/llms.txt` lists the expected pages, and `<page>.md` shows the expected content and directive after publishing.

## Reference

- [AI features overview](https://buildwithfern.com/learn/docs/ai-features/overview.md)
- [llms.txt](https://buildwithfern.com/learn/docs/ai-features/llms-txt.md)
- [Markdown access](https://buildwithfern.com/learn/docs/ai-features/markdown.md)
- [Agent directives](https://buildwithfern.com/learn/docs/ai-features/agent-directives.md)
- [Customize LLM output](https://buildwithfern.com/learn/docs/ai-features/customize-llm-output.md)
- [Ask Fern](https://buildwithfern.com/learn/docs/ai-features/ask-fern/overview.md)
- [MCP server](https://buildwithfern.com/learn/docs/ai-features/mcp-server.md)
- [Host agent skills](https://buildwithfern.com/learn/docs/ai-features/host-skills.md)
37 changes: 37 additions & 0 deletions fern/products/home/pages/fern-instructions/docs/analytics.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title: Add analytics to Fern docs
slug: fern-instructions/docs/analytics
description: Connect PostHog, Google Analytics and Tag Manager, Segment, Mixpanel, FullStory, or Intercom to a Fern docs site.
---

Use this to track readers or add a support widget.

## Workflow

1. Ask the user which tool they use and for its public key or ID. Don't invent IDs.
2. Add it under `analytics` (or `integrations` for support tools) in `docs.yml`, using the key names from that tool's page. For example:

```yaml
analytics:
posthog:
api-key: phc_xxxxxxxx
gtm:
container-id: GTM-XXXXXXX
```

3. Publish and confirm events arrive in the tool.

## Rules

- Use the built-in integrations rather than adding tracking scripts through `js`.
- Fern also has built-in web analytics in the Dashboard and `llms.txt` analytics. Check whether those already answer the user's question.

## Verify

- After publishing, page views show in the tool. The analytics events page lists what Fern sends.

## Reference

- [Integrations overview](https://buildwithfern.com/learn/docs/integrations/overview.md)
- [PostHog](https://buildwithfern.com/learn/docs/integrations/analytics/posthog.md), [Google](https://buildwithfern.com/learn/docs/integrations/analytics/google.md), [Segment](https://buildwithfern.com/learn/docs/integrations/analytics/segment.md), [Mixpanel](https://buildwithfern.com/learn/docs/integrations/analytics/mixpanel.md), [FullStory](https://buildwithfern.com/learn/docs/integrations/analytics/fullstory.md), [Intercom](https://buildwithfern.com/learn/docs/integrations/support/intercom.md)
- [Analytics events](https://buildwithfern.com/learn/docs/integrations/analytics/events.md)
Loading
Loading