Skip to content
Merged
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
6 changes: 5 additions & 1 deletion web/content/docs/file/review-bot-brief.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ description: 'A complete, copy-paste operating document for a Relayfile-backed P
---

<Note>
**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 `<angle-bracket>` placeholder — `<owner>/<repo>` and the specialist name are the two you set once, and `<run-id>`, `<pr-dir>`, `<pull-number>`, `<TICKET>`, `<sha>`, `<model-id>`, and `<opId>` 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).
</Note>
Expand Down
21 changes: 15 additions & 6 deletions web/content/docs/file/review-bot.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand All @@ -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)).

<Note>
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.
</Note>
Expand Down Expand Up @@ -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 `<angle-bracket>` placeholders before handing it over: `<owner>/<repo>` and the specialist name are set once, while `<run-id>`, `<pr-dir>`, `<pull-number>`, `<TICKET>`, `<sha>` and `<opId>` are filled per run.

## Tear down

```bash
Expand All @@ -426,9 +438,6 @@ rm -rf ./relayfile-mount
`relayfile workspace join <id> --name <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.
</Warning>

<BannerLink href="/docs/file/review-bot-brief" icon="bot">
Copy-paste agent brief — the same contract written for the agent itself, ready to drop in as `AGENTS.md`.
</BannerLink>

<CardGroup cols={2}>
<Card title="Mounting from a sandbox" href="/docs/file/mounting">
Expand All @@ -440,7 +449,7 @@ rm -rf ./relayfile-mount
<Card title="Real-time sync" href="/docs/file/realtime-sync">
Why the orchestrator sees a specialist's write on the next read.
</Card>
<Card title="Review bot agent brief" href="/docs/file/review-bot-brief">
The copy-paste operating document to hand the agent.
<Card title="CLI reference" href="/docs/file/cli">
Every flag used in this guide.
</Card>
</CardGroup>
20 changes: 15 additions & 5 deletions web/lib/product-docs-nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
}

Expand All @@ -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',
Expand All @@ -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',
Expand Down Expand Up @@ -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}`;
24 changes: 18 additions & 6 deletions web/lib/test/product-docs.test.ts
Original file line number Diff line number Diff line change
@@ -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', () => {
Expand All @@ -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', () => {
Expand Down
Loading