Files
beardrive/web/docs
4dfe6f44f0 feat(history): undo a file an agent run created (BEA-35) (#82)
History could restore an edit or a deletion, but a file a run CREATED was
the one thing it couldn't reverse — the ADDED row said so in copy and
offered no button. The missing capability was a hub-written delete op:
restore.go only ever journaled puts.

POST /api/p/<id>/remove journals exactly one journal.KindDelete op under
the hub's own device identity, behind restore's gates (gateUpload,
PermWrite, cleanUploadPath, quota CheckWrite/RecordUsage) plus a volume-
snapshot existence check so the API 404s on what the tree doesn't show.
Commit's journal-append tail moves into RemoteSource.appendOp, which both
writes now share — one writer per journal, unchanged.

The ADDED-in-a-run row gets an "undo — remove file" control that confirms
first (it reaches every synced device), and the DELETED row it leaves
behind restores the file with its original bytes.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 07:11:20 +09:00
..

docs.beardrive.ai

The public product documentation: CLI, sync model, self-hosting. Astro + Starlight, static output, Pagefind search.

npm install
npm run dev       # http://localhost:4321
npm run build     # -> dist/
npm run preview

Why this is a standalone site

Unlike the hub frontend (internal/webapp/static) and the cloud landing page (cloud/internal/landing/dist), this is not embedded into a Go binary:

  • Docs change far more often than the binary. Embedding them would mean a Go rebuild and redeploy to fix a typo.
  • A Pagefind search index has no business shipping inside every self-hoster's install.

It lives in the OSS repo because that is what it documents. "Edit this page" resolves to something an outside contributor can open a PR against.

Design tokens

scripts/tokens.mjs reads the @theme block in internal/webapp/frontend/src/tw.css — the source of truth for the BearDrive palette — and emits src/styles/tokens.gen.css. That file is generated, gitignored, and regenerated by npm run dev and npm run build, so the palette cannot drift. src/styles/custom.css maps Starlight's --sl-color-* variables onto it and invents no colors of its own.

(The cloud landing page can't do this — it sits in a different Go module and keeps a copy of the tokens, policed by its own check-tokens.mjs.)

Adding a page

Drop a .md file under src/content/docs/<section>/ with title and description frontmatter, then add its slug to the sidebar in astro.config.mjs. Sidebar order is explicit, not alphabetical.

Write description for every page: it is the meta description, the search result snippet, and what llms.txt shows.

llms.txt

starlight-llms-txt generates /llms.txt, /llms-small.txt, and /llms-full.txt at build time.

Convention puts llms.txt at the root domain, not a docs subdomain — so beardrive.ai/llms.txt should redirect or proxy to docs.beardrive.ai/llms.txt. That redirect lives in the cloud landing page and is the one cross-repo coordination point this split introduces.

Structure

The sidebar order in astro.config.mjs is the recommended path, and the recommended path is agent-first:

  • Start here — what it is, set up with your agent, first hour. No brew install appears in this group.
  • Working with agents — the workflows the product exists for.
  • Manual setup (optional) — the CLI route: install, set up by hand, skills and hooks in detail. Same destination, more steps; one click away, never on the critical path.
  • Use cases — job-shaped titles ("Share work across your team's agents"), persona named in the first line and in the description. These pages ROUTE: who it's for, what you get, the one setup difference, links out. The moment one starts teaching a feature, it links to the guide that owns it instead.
  • Self-hosting, Reference, Concepts — unchanged in intent.

Keep new onboarding content out of Manual. If a page teaches someone how to get started, it belongs in Start here and should say what to ask an agent, not what to type.

Deploying

Static output in dist/. Any static host works; build command npm run build, output directory dist, project root web/docs.

Redirects

The docs were reorganized around the agent-first path, so three old URLs moved:

Old New
/start/install /manual/install/
/start/quickstart /manual/setup-by-hand/
/guides/connect-an-agent /start/setup/

astro.config.mjs declares these, which in a static build emits meta-refresh pages — fine for humans, weak for search engines. Real 301s belong in the host.

Firebase Hosting (simplest static option on GCP — CDN, TLS, and custom domains included):

{
  "hosting": {
    "public": "dist",
    "ignore": ["firebase.json", "**/.*"],
    "redirects": [
      { "source": "/start/install", "destination": "/manual/install/", "type": 301 },
      { "source": "/start/quickstart", "destination": "/manual/setup-by-hand/", "type": 301 },
      { "source": "/guides/connect-an-agent", "destination": "/start/setup/", "type": 301 }
    ]
  }
}

Cloud Storage behind an external Application Load Balancer: put the rules in the URL map, which redirects before the bucket is ever reached.

gcloud compute url-maps edit docs-url-map   # pathMatchers[].pathRules[]:
#   - paths: ["/start/install"]
#     urlRedirect:
#       pathRedirect: "/manual/install/"
#       redirectResponseCode: MOVED_PERMANENTLY_DEFAULT
#       stripQuery: false

Whichever host wins, keep the Astro redirects block as well: it is the portable fallback, and it keeps local npm run preview honest.

Note that the build reads a file outside web/docs (the token source), so the host must check out the whole repository rather than just this subdirectory.