diff --git a/web/content/docs/file/review-bot-brief.mdx b/web/content/docs/file/review-bot-brief.mdx index 4d5460f..ef66d55 100644 --- a/web/content/docs/file/review-bot-brief.mdx +++ b/web/content/docs/file/review-bot-brief.mdx @@ -4,7 +4,11 @@ description: 'A complete, copy-paste operating document for a Relayfile-backed P --- - **This whole page is the brief.** Everything below is addressed to the agent, not to you. Take it with **Copy page as markdown** (top right) or `curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md`. + **This whole page is the brief.** Everything below is addressed to the agent, not to you — it is meant to be fetched as markdown and handed over, not browsed: + + ```bash + curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md + ``` Before handing it over, replace every `` placeholder — `/` and the specialist name are the two you set once, and ``, ``, ``, ``, ``, ``, and `` are filled per run or per finding. Verified against `relayfile` 0.10.53; it pairs with [Build a PR review bot](/docs/file/review-bot). diff --git a/web/content/docs/file/review-bot.mdx b/web/content/docs/file/review-bot.mdx index 1514113..266c96d 100644 --- a/web/content/docs/file/review-bot.mdx +++ b/web/content/docs/file/review-bot.mdx @@ -50,7 +50,7 @@ The integration stack is hosted either way — what changes is where the bot's p ## 1. Connect GitHub -One command logs you into Cloud, creates the workspace, runs the provider OAuth, waits for the first sync, and mounts the result: +One command logs you into Cloud, creates the workspace, runs the provider OAuth, and waits for the first sync. This is **provisioning** — a human does it once, on a machine with a browser, because the provider OAuth needs one: ```bash relayfile setup \ @@ -62,6 +62,8 @@ relayfile setup \ `--no-open` prints the login and connect URLs instead of launching a browser — always pass it when an agent (or CI) is driving the command, since a headless browser launch burns the OAuth state. +The local mirror it leaves behind is for *you*: somewhere to `ls`, `cat` and `grep` the tree and see exactly what your agents will see. It is not how a deployed bot reads the workspace — cloud sandboxes mount per run in [step 5](#5-give-every-sandbox-the-same-workspace), and short-lived functions skip the mount entirely. `--local-dir` is required here only because `--skip-mount` still prompts for a directory ([relayfile#461](https://github.com/AgentWorkforce/relayfile/pull/461)). + Both URLs are short-lived. A Cloud device code expires in minutes and the Nango connect URL has its own TTL, so complete them while the command is still waiting. If it exits first, re-run the same line — a re-run reuses the workspace and only opens a new connect flow when the provider isn't connected yet. @@ -413,6 +415,16 @@ Alternatives: subscribe in-process with the SDK (`connectWebSocket({ onEvent })` Either way the reviewer wakes on provider state changing rather than on a request arriving — see [Events and webhooks](/docs/file/events). In the cloud, keep the subscriber in one long-lived orchestrator that spawns a sandbox per PR. +## Give your agent a guide for this + +Everything above is written for you. The same contract written for the agent — its environment, the orient-before-acting rules, its ACL boundaries, the `/runs` run protocol, discovery-first writeback, and how to confirm a write actually landed — is one markdown file you can hand it directly: + +```bash +curl -o AGENTS.md https://agentrelay.com/docs/file/markdown/review-bot-brief.md +``` + +Drop it in as `AGENTS.md`, `CLAUDE.md`, or a skill. Replace the `` placeholders before handing it over: `/` and the specialist name are set once, while ``, ``, ``, ``, `` and `` are filled per run. + ## Tear down ```bash @@ -426,9 +438,6 @@ rm -rf ./relayfile-mount `relayfile workspace join --name ` **renames an existing local entry** for that workspace id rather than adding a second one. If you're scripting workspace setup, check `relayfile workspace list` before and after. - - Copy-paste agent brief — the same contract written for the agent itself, ready to drop in as `AGENTS.md`. - @@ -440,7 +449,7 @@ rm -rf ./relayfile-mount Why the orchestrator sees a specialist's write on the next read. - - The copy-paste operating document to hand the agent. + + Every flag used in this guide. diff --git a/web/lib/product-docs-nav.ts b/web/lib/product-docs-nav.ts index 79ad751..6758978 100644 --- a/web/lib/product-docs-nav.ts +++ b/web/lib/product-docs-nav.ts @@ -29,6 +29,12 @@ export interface ProductDocSection { repo: string; /** Current published version, shown as a badge in the sidebar header. */ version?: string; + /** + * Slugs that are built and indexed but deliberately kept out of the sidebar — + * pages whose real audience is an agent fetching the `.md` mirror, not a + * human browsing the nav. + */ + unlistedSlugs?: string[]; nav: NavGroup[]; } @@ -38,6 +44,8 @@ export const fileSection: ProductDocSection = { tagline: 'The event layer for AI agents.', repo: 'AgentWorkforce/relayfile', version: '0.10.53', + // Handed to an agent as markdown from the review-bot guide, not browsed. + unlistedSlugs: ['review-bot-brief'], nav: [ { title: 'Start', @@ -49,10 +57,7 @@ export const fileSection: ProductDocSection = { }, { title: 'Guides', - items: [ - { title: 'Build a PR review bot', slug: 'review-bot' }, - { title: 'Review bot agent brief', slug: 'review-bot-brief' }, - ], + items: [{ title: 'Build a PR review bot', slug: 'review-bot' }], }, { title: 'Concepts', @@ -221,7 +226,12 @@ export function getProductSectionForPath(pathname: string): ProductDocSection | } export function getProductDocSlugs(section: ProductDocSection): string[] { - return [...new Set(section.nav.flatMap((group) => group.items.map((item) => item.slug)))]; + return [ + ...new Set([ + ...section.nav.flatMap((group) => group.items.map((item) => item.slug)), + ...(section.unlistedSlugs ?? []), + ]), + ]; } export const productBasePath = (section: ProductDocSection): string => `/docs/${section.id}`; diff --git a/web/lib/test/product-docs.test.ts b/web/lib/test/product-docs.test.ts index 5502b09..ccaa63f 100644 --- a/web/lib/test/product-docs.test.ts +++ b/web/lib/test/product-docs.test.ts @@ -1,6 +1,11 @@ import { describe, expect, it } from 'vitest'; -import { factorySection, fileSection, getProductSearchIndex } from '../product-docs'; +import { + factorySection, + fileSection, + getProductDocSlugs, + getProductSearchIndex, +} from '../product-docs'; describe('Factory product docs', () => { it('publishes issue routing in navigation and scoped search', () => { @@ -24,13 +29,20 @@ describe('Factory product docs', () => { }); describe('Relayfile product docs', () => { - it('publishes both review-bot guides in a Guides group', () => { + it('lists only the human guide in the sidebar', () => { const guides = fileSection.nav.find((group) => group.title === 'Guides'); - expect(guides?.items).toEqual([ - { title: 'Build a PR review bot', slug: 'review-bot' }, - { title: 'Review bot agent brief', slug: 'review-bot-brief' }, - ]); + expect(guides?.items).toEqual([{ title: 'Build a PR review bot', slug: 'review-bot' }]); + }); + + it('still builds and indexes the agent brief, unlisted', () => { + const navSlugs = fileSection.nav.flatMap((group) => group.items.map((item) => item.slug)); + + expect(navSlugs).not.toContain('review-bot-brief'); + expect(fileSection.unlistedSlugs).toContain('review-bot-brief'); + // getProductDocSlugs drives the page, og and markdown routes, so the .md + // endpoint the guide links to must stay in it. + expect(getProductDocSlugs(fileSection)).toContain('review-bot-brief'); }); it('indexes the review-bot guide, including the cloud path', () => {