From 8fc44dc2258ffff0da454c246331248f1985493e Mon Sep 17 00:00:00 2001 From: Leon Cheng Date: Fri, 21 Aug 2026 20:21:28 -0400 Subject: [PATCH] feat: add architecture docs center --- CONTRIBUTING.md | 6 +- README.md | 6 +- client/components/app-shell.tsx | 10 +- client/ds/markdown.tsx | 20 +++- client/lib/docs.ts | 126 ++++++++++++++++++++++++++ client/main.tsx | 4 + client/pages/DocPage.tsx | 72 +++++++++++++++ client/pages/Docs.tsx | 141 +++++++++++++++++++++++++++++ client/styles.css | 28 ++++++ docs/architecture.md | 115 +++++++++++++++++++++++ docs/contributing/index.html | 1 + scripts/pr-screenshots.ts | 2 +- tests/docs.test.ts | 39 ++++++++ tests/e2e/palette.ui.spec.ts | 8 ++ tests/e2e/screenshots.ui.spec.ts | 6 +- tests/e2e/smoke.ui.spec.ts | 30 +++++- tests/fixtures/pr-screenshots.json | 4 + tests/pr-screenshots.test.ts | 5 + vite.config.ts | 11 ++- 19 files changed, 619 insertions(+), 15 deletions(-) create mode 100644 client/lib/docs.ts create mode 100644 client/pages/DocPage.tsx create mode 100644 client/pages/Docs.tsx create mode 100644 docs/architecture.md create mode 100644 tests/docs.test.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29ff0500..87dc449c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,8 @@ Thank you for improving custom-dca-opencode. This guide covers the repository's development workflow and the checks that pull requests must pass. Use the self-contained [visual reading index](docs/contributing/index.html) to choose a -contributor pathway, or continue here for the canonical workflow. +contributor pathway, open `/docs` in the running app for the architecture-focused docs center, +or continue here for the canonical workflow. ## Before you start @@ -55,6 +56,9 @@ The request path is: Browser -> React/Vite SPA -> Express BFF -> opencode serve ``` +See [docs/architecture.md](docs/architecture.md) for the detailed request and event flows, +state ownership, safety boundaries, and extension map. + - [`client/`](client/) contains the React SPA and design-system primitives. - [`server/`](server/) contains API routes, credentials, directory validation, SSE fan-out, local git operations, notifications, and forge integrations. diff --git a/README.md b/README.md index 69975352..e8947552 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,8 @@ starts a second OpenCode server; it uses `OPENCODE_URL` from `.env`. The OpenCode 1.18.21 compatibility check is recorded in [`docs/opencode-1.18.21-api-audit.md`](docs/opencode-1.18.21-api-audit.md). See [`CONTRIBUTING.md`](CONTRIBUTING.md) for the development and pull request workflow. -The same contributor material has a themed [visual reading index](docs/contributing/index.html). +The running app exposes the architecture and canonical guides at `/docs`; the same contributor +material also has a standalone themed [visual reading index](docs/contributing/index.html). ### Open on a phone @@ -195,6 +196,9 @@ The BFF exists because: it holds the server credential, fans one upstream SSE st to many browser clients, threads `?directory=` per project, and runs the things the OpenCode API doesn't expose (git history, forge APIs, notification transport). +See [`docs/architecture.md`](docs/architecture.md) for conversation and event flows, state +ownership, safety boundaries, and the extension map. + ## Safety `opencode serve` runs agent tools **directly on the host as your user** — there is no diff --git a/client/components/app-shell.tsx b/client/components/app-shell.tsx index 99e1bd97..73fed1f3 100644 --- a/client/components/app-shell.tsx +++ b/client/components/app-shell.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from "react"; -import { Search, Smartphone } from "lucide-react"; +import { BookOpen, Search, Smartphone } from "lucide-react"; import { useTheme } from "next-themes"; import { NavLink, Outlet, useLocation, useNavigate } from "react-router-dom"; @@ -93,6 +93,7 @@ export function AppShell() { navigation: [ { id: "home", title: "Home", to: scopedPath("/"), keywords: ["sessions"] }, { id: "tools", title: "Tools", to: scopedPath("/tools"), keywords: ["mcp", "lsp", "permissions"] }, + { id: "docs", title: "Docs", to: scopedPath("/docs"), keywords: ["architecture", "contributing", "internals"] }, { id: "notifications", title: "Notifications", @@ -135,7 +136,8 @@ export function AppShell() {