diff --git a/README.md b/README.md index dbda19f50..698655e28 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ A full-stack plugin can bring the routes, APIs, database schema, hooks, SSR-awar **You own the whole application.** Your app, data, deployment, and ejected UI stay yours. BTST runs inside your stack as an open-source dependency you can inspect, fork, or replace—never as a required hosted control plane. + + +Real output from the repository's generated Next.js application. + [](https://www.npmjs.com/package/@btst/stack) [](https://opensource.org/licenses/MIT) diff --git a/docs/assets/architecture.png b/docs/assets/architecture.png deleted file mode 100644 index eaea7b9fd..000000000 Binary files a/docs/assets/architecture.png and /dev/null differ diff --git a/docs/assets/blog-demo-1.png b/docs/assets/blog-demo-1.png deleted file mode 100644 index 98422e45c..000000000 Binary files a/docs/assets/blog-demo-1.png and /dev/null differ diff --git a/docs/assets/blog-demo-2.png b/docs/assets/blog-demo-2.png deleted file mode 100644 index 7ba8d5f32..000000000 Binary files a/docs/assets/blog-demo-2.png and /dev/null differ diff --git a/docs/assets/blog-demo-3.png b/docs/assets/blog-demo-3.png deleted file mode 100644 index bb48ae270..000000000 Binary files a/docs/assets/blog-demo-3.png and /dev/null differ diff --git a/docs/assets/blog-demo.png b/docs/assets/blog-demo.png deleted file mode 100644 index e59b34907..000000000 Binary files a/docs/assets/blog-demo.png and /dev/null differ diff --git a/docs/assets/chat-demo-1.png b/docs/assets/chat-demo-1.png deleted file mode 100644 index 6f55d293f..000000000 Binary files a/docs/assets/chat-demo-1.png and /dev/null differ diff --git a/docs/assets/chat-demo.png b/docs/assets/chat-demo.png deleted file mode 100644 index fbddf4070..000000000 Binary files a/docs/assets/chat-demo.png and /dev/null differ diff --git a/docs/assets/form-builder-demo-1.png b/docs/assets/form-builder-demo-1.png deleted file mode 100644 index 1ca2f2afb..000000000 Binary files a/docs/assets/form-builder-demo-1.png and /dev/null differ diff --git a/docs/assets/form-builder-demo-2.png b/docs/assets/form-builder-demo-2.png deleted file mode 100644 index cdaf4808f..000000000 Binary files a/docs/assets/form-builder-demo-2.png and /dev/null differ diff --git a/docs/assets/form-builder-demo-3.png b/docs/assets/form-builder-demo-3.png deleted file mode 100644 index 79dd2dc5a..000000000 Binary files a/docs/assets/form-builder-demo-3.png and /dev/null differ diff --git a/docs/assets/form-builder-demo.png b/docs/assets/form-builder-demo.png deleted file mode 100644 index 6065a6efd..000000000 Binary files a/docs/assets/form-builder-demo.png and /dev/null differ diff --git a/docs/assets/openapi-demo.png b/docs/assets/openapi-demo.png deleted file mode 100644 index 5992c7b07..000000000 Binary files a/docs/assets/openapi-demo.png and /dev/null differ diff --git a/docs/assets/product-proof/README.md b/docs/assets/product-proof/README.md new file mode 100644 index 000000000..b0991f79b --- /dev/null +++ b/docs/assets/product-proof/README.md @@ -0,0 +1,77 @@ +# BTST product-proof asset kit + +This kit pairs short, causal claims with real screens from the repository's generated Next.js application. The only conceptual asset is the editable ownership diagram. No mock product UI or model output is fabricated. + +## Visual contract + +- Preserve the graphite BTST symbol and use the `BTST` name consistently. +- Use graphite, paper, fog, and restrained cobalt; product screenshots retain their real UI colors. +- Set presentation copy in Geist Sans and labels in Geist Mono when available. +- Keep reusable proof frames at 16:9. A narrow claim rail explains what the screenshot proves; the larger area remains authentic product evidence. +- Annotate only a causal connection or visible outcome. Do not add invented metrics, version badges, customer logos, or testimonial claims. + +Product UI is captured deterministically in its dark theme. The raster proof frames are self-contained and do not change with the host color scheme; the ownership SVG intentionally uses a fixed light canvas. Whenever an asset or its frame changes, verify the README and docs embedding in both host themes so borders, captions, and surrounding contrast remain clear. + +## Capture recipe + +The committed outputs are deterministic captures of a freshly generated app. The recipe uses Node 22, the repository-pinned `pnpm@10.17.1`, Playwright Chromium, a 1440×900 viewport at DPR 1, UTC, `en-US`, dark theme, and reduced motion. Sharp frames each raw screenshot as a 1600×900 WebP. + +The coherent fixture is [dogfood-data.json](../../../e2e/product-proof/dogfood-data.json). It contains no personal data and describes one release-evidence story across Blog, Comments, Form Builder, UI Builder, Media, OpenAPI, Route Docs, and AI Chat. The capture workflow seeds Blog posts, an approved Comment, a published UI Builder page, and one exact-name Media asset through the registered plugin's direct multipart upload route. It removes that Media asset before and after every run, verifies the stored record, filters the generated library route, and requires exactly one visible asset card. Form Builder remains an unsaved interaction; OpenAPI and Route Docs are generated from the registered backend and client stacks. AI Chat requires both an empty authenticated-history API result and the visible empty-sidebar state before it types—but does not send—the fixture prompt. + +```bash +# From the repository root, with Node 22 active +corepack pnpm install --frozen-lockfile +corepack pnpm --filter e2e exec playwright install chromium +corepack pnpm build +SHADCN_VERSION=4.19.1 bash scripts/codegen/setup-nextjs.sh + +# In one terminal +PRODUCT_PROOF_BASE_URL=http://localhost:3006 \ + corepack pnpm -F nextjs exec next dev -p 3006 + +# In another terminal +PRODUCT_PROOF_BASE_URL=http://localhost:3006 \ + corepack pnpm --filter e2e exec node product-proof/capture.mjs + +node scripts/product-proof/check-assets.mjs \ + docs/assets/product-proof/manifest.json +bash scripts/codegen/cleanup.sh nextjs +``` + +The setup script defaults `SHADCN_VERSION` to `4.19.1`; change it only as an intentional toolchain update followed by a full recapture. The capture script removes and recreates only its known Blog, Comments, UI Builder, and Media fixtures, waits for fonts and network idle, disables motion and dev overlays, rejects stale naming or personal fixture text, captures the real routes, and writes static outputs. Run it twice from a fresh generated app and compare SHA-256 hashes when changing the workflow itself. + +Deliverable filenames are stable public references: keep a filename when refreshing the same proof, and rename it only when the evidence meaning changes, updating the manifest and every consumer atomically. `manifest.version` is the manifest/checker schema revision. Increment `manifest.assetRevision` whenever capture copy, source data, layout, or output pixels change. + +## Aperture and truth boundaries + +| Asset | Real state captured | Claim boundary | +| --- | --- | --- | +| README hero | Focused Blog route | Category promise plus one authentic, legible product result | +| Blog | Published Blog route | Canonical full-stack slice | +| Form Builder | Unsaved editor with three fields and live preview | Rich interactive UI; no submission claim | +| UI Builder | Persisted published page in editor | CMS-backed page composition | +| OpenAPI | Live Scalar reference route | Backend-only plugin with generated reference UI | +| AI Chat | Authenticated empty shell with typed prompt | No model response or tool result claimed | +| Code → result | Current Blog backend and client registrations plus published route | Causal registration-to-outcome pattern | + +The code excerpt is derived from the generated app's current [backend registration](../../../scripts/codegen/files/nextjs/lib/stack.ts) and [client registration](../../../scripts/codegen/files/nextjs/lib/stack-client.tsx). Capture fails with a source-specific drift error if either critical registration changes. It documents the registrations in the captured all-plugin dogfood app; no separate scaffold is implied. + +Every representative frame fits the entire 1440×900 product screen into a 16:9 aperture with `contain`; navigation, sidebar, and controls remain present rather than being cover-cropped. The README hero uses one intentional, full-width close crop of the real Blog route so its essential promise and proof remain legible at a roughly 358 px GitHub mobile width. Matte space may be added around a representative screen, but no claimed workflow or explanatory copy may be clipped. Rails and README copy must be completely visible at 1600×900 and remain readable at repository width. + +## Budgets and accessibility + +`manifest.json` is the source of truth for dimensions, individual byte budgets, the 1.8 MB whole-kit ceiling, alt text, captions, textual sources, prohibited copy, narrowly scoped source exceptions, and the kit/schema revisions. The checker reads SVG and WebP dimensions without relying on a globally installed image tool and scans every declared textual source case-insensitively. Source exceptions cover only exact-case lowercase npm package tokens and the exact canonical website URL; uppercase legacy lockups remain prohibited even inside an otherwise excepted source. + +Use the manifest's `alt` value when embedding an asset. Place its `caption` immediately below the image when the surrounding copy does not already state the same evidence. Decorative images must be explicitly marked and use empty alt text; this kit currently has no decorative deliverables. + +The exact project-owned symbol used in the README hero is retained as the editable [SVG source](source/btst-symbol.svg). + +## Verification record + +2026-09-01, Node 22 and `pnpm@10.17.1`: + +- Two consecutive capture runs produced identical SHA-256 hashes for all eight deliverables after the final copy and source-derivation changes. +- The asset checker passed at 206,291 bytes total against the 1.8 MB ceiling; all ten contract tests passed, including backend/client drift failures and scoped prohibited-copy exceptions. +- The generated app persisted one exact-name Media upload through the registered direct-upload route, displayed exactly one matching library card, and removed the database record and local file after each run. +- The GitHub Markdown API rendered the stable README hero reference in GFM mode. The pushed branch README was also checked at a 358 px browser viewport: the category promise and authentic Blog result remained legible without horizontal overflow. +- A production docs build rendered the corrected AI Chat proof at desktop and 390×844 mobile widths in both light and dark host themes. The image reported its complete 1600×900 natural dimensions, stayed within the content column, and produced no framework error overlay. diff --git a/docs/assets/product-proof/ai-chat-proof.webp b/docs/assets/product-proof/ai-chat-proof.webp new file mode 100644 index 000000000..94a999e00 Binary files /dev/null and b/docs/assets/product-proof/ai-chat-proof.webp differ diff --git a/docs/assets/product-proof/blog-proof.webp b/docs/assets/product-proof/blog-proof.webp new file mode 100644 index 000000000..c1e3769f4 Binary files /dev/null and b/docs/assets/product-proof/blog-proof.webp differ diff --git a/docs/assets/product-proof/code-to-result.webp b/docs/assets/product-proof/code-to-result.webp new file mode 100644 index 000000000..df0e96ba1 Binary files /dev/null and b/docs/assets/product-proof/code-to-result.webp differ diff --git a/docs/assets/product-proof/form-builder-proof.webp b/docs/assets/product-proof/form-builder-proof.webp new file mode 100644 index 000000000..83a2d0cc2 Binary files /dev/null and b/docs/assets/product-proof/form-builder-proof.webp differ diff --git a/docs/assets/product-proof/manifest.json b/docs/assets/product-proof/manifest.json new file mode 100644 index 000000000..02aa53ac0 --- /dev/null +++ b/docs/assets/product-proof/manifest.json @@ -0,0 +1,139 @@ +{ + "version": 1, + "assetRevision": 3, + "kitMaxBytes": 1800000, + "forbiddenText": [ + "Better Stack", + "Better-Stack", + "Sarah", + "grandmother", + "$50,000", + "$200,000", + "@olliethedev", + "@BTST/STACK" + ], + "textSources": [ + "../../../e2e/product-proof/capture.mjs", + "../../../e2e/product-proof/dogfood-data.json", + "../../../e2e/product-proof/registration-contract.mjs", + "../../../scripts/codegen/files/nextjs/lib/stack.ts", + "../../../scripts/codegen/files/nextjs/lib/stack-client.tsx", + "../../../scripts/codegen/files/nextjs/components/navbar.tsx", + "../../../packages/cli/src/templates/nextjs/components/navbar.tsx.hbs", + "../../../packages/cli/src/templates/react-router/components/navbar.tsx.hbs", + "../../../packages/cli/src/templates/tanstack/components/navbar.tsx.hbs", + "ownership-diagram.svg", + "source/btst-symbol.svg" + ], + "textSourceAllowlist": { + "../../../scripts/codegen/files/nextjs/lib/stack.ts": [ + { + "term": "@BTST/STACK", + "context": "lowercaseNpmPackageToken", + "token": "@btst/stack" + }, + { + "term": "Better-Stack", + "context": "canonicalWebsiteUrl", + "url": "https://www.better-stack.ai" + } + ], + "../../../scripts/codegen/files/nextjs/lib/stack-client.tsx": [ + { + "term": "@BTST/STACK", + "context": "lowercaseNpmPackageToken", + "token": "@btst/stack" + } + ] + }, + "assets": [ + { + "file": "readme-hero.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 350000, + "alt": "BTST promise above a focused view of the real Blog route from the generated application.", + "caption": "Add complete capabilities while keeping the React application, shown with an authentic Blog result.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "ownership-diagram.svg", + "format": "svg", + "width": 1600, + "height": 900, + "maxBytes": 80000, + "alt": "Diagram separating the application and operating boundaries a team owns from the BTST runtimes and plugins running inside it.", + "caption": "BTST composes client and backend plugins inside the application; the app shell, ejected views, database, deployment, and external services remain yours.", + "source": "ownership-diagram.svg", + "decorative": false + }, + { + "file": "blog-proof.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 240000, + "alt": "Real BTST Blog page with three published product-update posts in the generated Next.js application.", + "caption": "Blog is the canonical full-stack proof: one plugin supplies routes, backend behavior, client UI, and a visible published result.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "form-builder-proof.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 280000, + "alt": "Real BTST Form Builder with Email, Text Area, and Select fields on the canvas and in the live form preview.", + "caption": "The shipped Form Builder provides a drag-and-drop workflow with a live form preview.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "ui-builder-proof.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 280000, + "alt": "Real BTST UI Builder editing a release-evidence page with layers, canvas, status, and component properties.", + "caption": "UI Builder composes a published page against the same application runtime and deployment boundary.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "openapi-proof.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 250000, + "alt": "Real Scalar API reference generated by the backend-only BTST OpenAPI plugin.", + "caption": "OpenAPI shows that a BTST plugin may add a focused backend capability without a matching client plugin.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "ai-chat-proof.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 220000, + "alt": "Real authenticated BTST AI Chat shell with an empty conversation-history sidebar, attachment control, and a product-context prompt ready to send.", + "caption": "The capture proves the shipped chat shell and prompt boundary; it deliberately does not fabricate a model response.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + }, + { + "file": "code-to-result.webp", + "format": "webp", + "width": 1600, + "height": 900, + "maxBytes": 260000, + "alt": "The current Blog backend and client registrations point to the real published Blog route they produce.", + "caption": "The code-to-result pattern connects the registered Blog backend and client halves with their visible product outcome.", + "source": "../../../e2e/product-proof/capture.mjs", + "decorative": false + } + ] +} diff --git a/docs/assets/product-proof/openapi-proof.webp b/docs/assets/product-proof/openapi-proof.webp new file mode 100644 index 000000000..146f1cee1 Binary files /dev/null and b/docs/assets/product-proof/openapi-proof.webp differ diff --git a/docs/assets/product-proof/ownership-diagram.svg b/docs/assets/product-proof/ownership-diagram.svg new file mode 100644 index 000000000..bdbf11b33 --- /dev/null +++ b/docs/assets/product-proof/ownership-diagram.svg @@ -0,0 +1,65 @@ + diff --git a/docs/assets/product-proof/readme-hero.webp b/docs/assets/product-proof/readme-hero.webp new file mode 100644 index 000000000..eae6beae9 Binary files /dev/null and b/docs/assets/product-proof/readme-hero.webp differ diff --git a/docs/assets/product-proof/source/btst-symbol.svg b/docs/assets/product-proof/source/btst-symbol.svg new file mode 100644 index 000000000..83ea5a423 --- /dev/null +++ b/docs/assets/product-proof/source/btst-symbol.svg @@ -0,0 +1,8 @@ + + diff --git a/docs/assets/product-proof/ui-builder-proof.webp b/docs/assets/product-proof/ui-builder-proof.webp new file mode 100644 index 000000000..eaad4b2a3 Binary files /dev/null and b/docs/assets/product-proof/ui-builder-proof.webp differ diff --git a/docs/assets/ui-builder-demo-1.gif b/docs/assets/ui-builder-demo-1.gif deleted file mode 100644 index e34e38a7e..000000000 Binary files a/docs/assets/ui-builder-demo-1.gif and /dev/null differ diff --git a/docs/content/docs/how-it-works.mdx b/docs/content/docs/how-it-works.mdx index d287cb89d..908be7e76 100644 --- a/docs/content/docs/how-it-works.mdx +++ b/docs/content/docs/how-it-works.mdx @@ -5,7 +5,13 @@ description: Understand the architecture and key concepts behind BTST. Here's a high-level overview of how BTST works: - + + +BTST composes client and backend plugins inside your application. Your app shell, ejected views, database, deployment, and external services remain yours. + + + +Register Blog with the backend and client stacks, then inspect the resulting route at `/pages/blog`. ## Server Side diff --git a/docs/content/docs/plugins/ai-chat.mdx b/docs/content/docs/plugins/ai-chat.mdx index 5f4f8e269..e2f9b0ded 100644 --- a/docs/content/docs/plugins/ai-chat.mdx +++ b/docs/content/docs/plugins/ai-chat.mdx @@ -7,18 +7,16 @@ import { Tabs, Tab } from "fumadocs-ui/components/tabs"; import { Callout } from "fumadocs-ui/components/callout"; import Image from "next/image"; -import chatDemo from "../../../assets/chat-demo.png"; -import chatDemo1 from "../../../assets/chat-demo-1.png"; +import aiChatProof from "../../../assets/product-proof/ai-chat-proof.webp"; -