Skip to content

Latest commit

 

History

History
154 lines (138 loc) · 8.08 KB

AGENTS.md

File metadata and controls

154 lines (138 loc) · 8.08 KB

Sourcegraph Docs - Agent Instructions

Documentation style

  • Write long-lived feature and configuration docs in the present tense for the behavior readers will use when the docs are published. Avoid time-relative wording such as "upcoming", "new", or "now" that requires later cleanup.
  • PRs for unreleased behavior can be ready for review. Coordinate merge timing with the relevant release or weekly update, and record that dependency in the PR description, not in customer prose.
  • Describe the current behavior concisely. Put release transitions and old/new comparisons in upgrade notes rather than permanent feature docs. Retain version-specific guidance only when readers still need it to use or upgrade supported releases.
  • Number ordered Markdown lists sequentially (1., 2., 3.), rather than writing every item as 1..

Build Commands

  • Type Check: npx tsc --noEmit
  • Package manager: pnpm (packageManager in package.json; mise install gives you the pinned Node and pnpm from .tool-versions). Never npm run
  • Build: pnpm run build
  • Dev: pnpm run dev
  • Lint: pnpm run lint (ESLint 9 flat config in eslint.config.mjs; React Compiler rules are warnings until the vendored src/components/search/docsearch code is rewritten)
  • Framework: Next.js 16. next build uses Turbopack; dev/build-content.mjs runs contentlayer2 build first, with its cache under .next/cache so Vercel keeps it between deploys, and with each .mdx file's mtime set from its content, since contentlayer2 keys its cache on mtime and a fresh clone resets those (workaround; drop once timlrx/contentlayer2#94 ships). next dev --webpack still uses the next-contentlayer2 webpack plugin to regenerate content on change (next.config.js applies it only in the dev phase). The request rewrite lives in src/proxy.ts; /api/releases and /api/versions opt into static caching with export const dynamic = 'force-static'
  • Checks: pnpm run check runs the checks in dev/checks.mjs (links, filenames, images); pnpm run build runs filenames and images first, so a finding from those fails a deploy. Links is not in the build: it runs as its own PR check (.github/workflows/check-links.yml)
  • Check redirects: node dev/check-redirects.mjs reports broken entries in src/data/redirects.ts (CI comments on PRs that break redirects; see the script header for what it checks). Not part of pnpm run check: main has hundreds of pre-existing findings, and CI only reports the ones a PR adds. When a check script crashes, CI comments that the check could not run, linking the job log, instead of failing the PR: an empty report says nothing about the PR
  • Prove changed links resolve on a deploy: node dev/verify-links-live.mjs --site <vercel-preview-url> prints a Markdown table for the PR description
  • Spell check: .github/workflows/spellcheck.yml runs dev/check-spelling.mjs on the lines a PR adds plus its title and description, and comments the findings (advisory, never fails the PR). Add product names and identifiers to cspell-allow-list.txt, in alphabetical order; the check reports out-of-order entries. CSpell is not a project dependency: npx cspell@10 --no-progress <file> to run it locally
  • Example hostnames: placeholder hostnames in docs are *.example.com (sourcegraph.example.com for the reader's instance, github.example.com for a code host, https://sourcegraph.example.com where a whole URL is meant); never <URL>, [hostname], or a $VARIABLE the reader has to guess. Example URLs use https://, except where needed, eg. loopback, in-cluster, proxy, and XML-namespace addresses. In a shell snippet a $VARIABLE is fine only when the same snippet exports it with an example value. .github/workflows/check-hostnames.yml runs dev/check-hostnames.mjs on the lines a PR adds and comments the findings with suggested changes (advisory, never fails the PR). dev/example-hostnames.json maps each recommended hostname to the placeholders seen in its place, as either literal text, a * glob, or a /regex/, matched case-insensitively with -, _, and . interchangeable; add to it when the check misses one, keeping keys and lists sorted. node dev/check-hostnames.mjs checks all of docs/ The 🤖 Sync generated docs PRs overwrite the SCHEMA_SYNC_START…SCHEMA_SYNC_END blocks and whole pages (self-hosted/observability/{alerts,dashboards}.mdx, cli/references/, ai/models.mdx, cody/capabilities/supported-models.mdx, admin/telemetry/); fix those in sourcegraph/sourcegraph instead. git log --author=sourcegraph-buildkite -- <file> shows whether a page is one

Links

  • pnpm run check links --check-anchors --check-self-links. CI comments on PRs that break links and fails the Broken links introduced by this PR check; see dev/check-links.mjs.
  • When moving a page or renaming a heading, update every link to it; a redirect in src/data/redirects.ts does not satisfy the check.
  • Link to this site with relative paths (/admin/config/site-config), never https://sourcegraph.com/docs/… or https://docs.sourcegraph.com/….
  • main has hundreds of pre-existing findings. To see only the ones your branch adds, as CI does, record the merge base with --format json and pass it as --baseline; --diff does not filter findings, it only scopes --check-external and the review comments to added lines:
base=$(git merge-base origin/main HEAD)
git worktree add --detach /tmp/docs-base "$base"
node dev/check-links.mjs --check-anchors --check-self-links --format json \
  --root /tmp/docs-base > /tmp/docs-base-links.json
git worktree remove /tmp/docs-base
git diff -U0 "$base" | pnpm run check links --check-anchors --check-self-links \
  --check-external --baseline /tmp/docs-base-links.json --diff /dev/stdin
  • Pipe the diff to --diff /dev/stdin, not --diff <(git diff ...): dev/checks.mjs spawns the check with only stdin/stdout/stderr, so the process-substitution descriptor is gone and the check fails with EBADF

PR check comments

The spelling, links, redirects, and example hostnames checks comment on the PR: a summary comment per check, plus an inline review comment with a suggestion block on each flagged line. After pushing, read them and follow the instructions they give (fix the spelling, the link, the redirect, or the hostname); do not work around a finding, and add a word to cspell-allow-list.txt only when it is correct.

gh pr checks <pr>
gh api repos/sourcegraph/docs/issues/<pr>/comments --paginate --jq '.[].body'
gh api repos/sourcegraph/docs/pulls/<pr>/comments --paginate \
    --jq '.[] | "\(.path):\(.line)\n\(.body)\n"'

Fork PRs get no comments; the findings are in the job log (gh run view <run-id> --log). The checks resolve their own comments on the next run.

Vercel build failures

  • Vercel shows build logs only to its team members, so .github/workflows/vercel-build-log.yml attaches the log to the Vercel Slack app's "failed to deploy" post in the SLACK_CHANNEL_ID channel and comments a link to it on the PR (see dev/vercel-build-log.mjs). The log itself never goes on the PR, since the repository is public.
  • It reads Vercel with the VERCEL_TOKEN repo secret, a token scoped to the sourcegraph-docs project that expires 2026-12-10; mint a new one with POST /v3/user/tokens?teamId=<team> and projectId in the body.
  • Slack needs the SLACK_BOT_TOKEN repo secret and SLACK_CHANNEL_ID repo variable. The bot is the Slack app in dev/vercel-build-log-slack-app-manifest.json; to recreate it, paste that manifest at https://api.slack.com/apps?new_app=1 (From a manifest), install it, copy its Bot User OAuth Token into the secret, and /invite @Vercel build log to the channel.

Branches

  • Prefix every branch with a name that identifies the human it belongs to (first name, username, or nickname), then a slash: marc/fix-moved-page-links. Agents use the name of the human they are working for, never their own