Add VitePress documentation site at /docs#32
Conversation
Add packages/docs as a VitePress documentation site served at /docs subpath. Includes scenario-based user guides (getting started, budget tracker, collaboration, formulas, keyboard shortcuts), API reference, and CLI documentation. Screenshots are captured from a docs harness page using Playwright and MemStore. - Add VitePress package with custom amber/gold theme - Add docs harness page with spreadsheet scenarios for screenshots - Add Playwright screenshot capture script - Update homepage nav: Developers → Docs with /docs link - Add dev proxy and CI build pipeline for docs - Add .gitignore entry for VitePress cache Co-Authored-By: Claude Opus 4.6 <[email protected]>
Add design document covering VitePress setup, screenshot capture pipeline, build/deployment architecture, and URL routing. Fix cp -r idempotency issue in build:all and CI workflow by clearing the target directory before copying. Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
📝 WalkthroughWalkthroughAdds a VitePress documentation site, integrates it into frontend routing and build, introduces a docs harness page and Playwright screenshot script, and updates GitHub Actions to build/copy docs into the frontend distribution for GitHub Pages deployment. Changes
Sequence Diagram(s)sequenceDiagram
participant Script as capture-docs-screenshots.mjs
participant Vite as Vite Dev Server
participant Browser as Playwright Browser
participant DOM as Docs Harness Page (DOM)
participant FS as File System
Script->>Script: Ensure Playwright & browsers present
Script->>Vite: Start frontend dev server (harness)
Script->>Browser: Launch browser context (900x600)
Browser->>Vite: Request /harness/docs
Vite->>DOM: Serve harness page
DOM-->>Script: Expose scenarios (data-docs-scenario-id/ready)
loop For each scenario
Script->>Browser: Wait fonts, disable animations
Script->>DOM: Query scenario container
Browser-->>FS: Capture and save PNG to docs/public/images
end
Script->>Browser: Close browser
Script->>Vite: Close server
Script->>Script: Log completion
sequenceDiagram
participant GHA as GitHub Actions
participant Build as Build Steps
participant Frontend as Frontend SPA Build
participant Docs as VitePress Build
participant Combine as Copy/Combine
participant Pages as GitHub Pages Deploy
GHA->>Build: Trigger publish-ghpage workflow
Build->>Frontend: pnpm build (frontend)
Build->>Docs: pnpm vpdocs build
Docs-->>Build: .vitepress/dist produced
Build->>Combine: rm packages/frontend/dist/docs && copy docs build into frontend dist
Combine-->>Build: Unified dist (SPA + /docs)
Build->>Pages: Deploy unified dist to GitHub Pages
Pages-->>GHA: Deployment complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Verification: verify:selfResult: ✅ PASS in 96.6s
Verification: verify:integrationResult: ✅ PASS |
Use full paths for backtick-wrapped file references so the doc-staleness checker can resolve them. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (6)
packages/frontend/vite.config.ts (1)
103-109: Consider documenting the hardcoded port dependency.The proxy target port
5174matchespackages/docs/package.jsondev script. A brief comment would help future maintainers understand this coupling.Optional: Add a clarifying comment
server: { proxy: { + // Forward to VitePress dev server (port defined in packages/docs/package.json) "/docs": { target: "http://localhost:5174",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/frontend/vite.config.ts` around lines 103 - 109, The proxy entry for "/docs" in vite.config.ts hardcodes target: "http://localhost:5174" which couples this frontend to the docs dev server port; add a concise inline comment above the proxy block referencing that 5174 must match the dev script in packages/docs/package.json (or suggest using an env var like DOCS_DEV_PORT) so future maintainers understand the dependency and how to change it.packages/frontend/src/app/harness/docs/page.tsx (1)
48-57: Refactor.then()chain to async/await for consistency.The coding guidelines prefer async/await over
.then()chains. This would also improve readability of the setup and initialization flow.♻️ Proposed refactor using async IIFE
let destroyed = false; let instance: Awaited<ReturnType<typeof initialize>> | undefined; - setup().then(() => initialize(el, { theme, store, readOnly: true, hideFormulaBar: true, hideAutofillHandle: true })).then((s) => { - if (destroyed) { - s.destroy(); - return; - } - instance = s; - setReady(true); - }); + (async () => { + await setup(); + const s = await initialize(el, { + theme, + store, + readOnly: true, + hideFormulaBar: true, + hideAutofillHandle: true, + }); + if (destroyed) { + s.destroy(); + return; + } + instance = s; + setReady(true); + })(); return () => { destroyed = true; instance?.destroy(); };As per coding guidelines: "Use async/await instead of .then() chains for promise handling".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/frontend/src/app/harness/docs/page.tsx` around lines 48 - 57, Refactor the promise chain that calls setup() and initialize(...) into an async/await flow: create an async function or IIFE that awaits setup() and then awaits initialize(el, { theme, store, readOnly: true, hideFormulaBar: true, hideAutofillHandle: true }), then perform the same destroyed check (call s.destroy() if destroyed), assign the result to the existing instance variable, and call setReady(true); ensure you preserve the destroyed and instance variables, keep the same call arguments (el, theme, store), and preserve error behavior (propagate or catch as the surrounding code expects).packages/frontend/scripts/capture-docs-screenshots.mjs (1)
93-94: Magic timeout value for render stabilization.The 500ms delay is intended to wait for async renders, but the comment could be more specific about what's being waited for. Consider extracting to a named constant or adding more context.
Optional: Add context to the timeout
+ // Brief delay for canvas/grid rendering to stabilize after React state updates // Wait for all async renders to complete await page.waitForTimeout(500);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/frontend/scripts/capture-docs-screenshots.mjs` around lines 93 - 94, The hard-coded 500ms magic timeout in page.waitForTimeout(500) is unclear; replace the literal with a named constant (e.g. RENDER_STABILIZATION_MS) and add a short comment describing exactly what async renders or resources you're waiting for (e.g. "wait for client-side hydration / async data render to complete"), or preferably replace with a deterministic wait (e.g. page.waitForSelector or page.waitForResponse) if possible; update the call in capture-docs-screenshots.mjs where page.waitForTimeout is used to reference the new constant or deterministic wait to make the intent explicit.packages/docs/guide/build-a-budget.md (1)
23-25: Consider adding language identifiers to formula code blocks.Static analysis flagged multiple fenced code blocks without language specifiers (lines 23, 29, 37, 66, 82, 90, 98, 106). Since these contain spreadsheet formulas rather than code, you could use
```textor```excelto satisfy the linter while preserving clarity.This is optional since formula blocks don't have standard syntax highlighting.
Example fix for one block
-``` +```text =SUM(B2:B7)</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@packages/docs/guide/build-a-budget.mdaround lines 23 - 25, Add a language
identifier to fenced code blocks containing spreadsheet formulas (e.g., change
the block containing the formula=SUM(B2:B7)to usetext orexcel) so
the linter recognizes them; scan the file for similar formula blocks (the other
instances flagged) and update each fence to include a language specifier while
keeping the formula content unchanged.</details> </blockquote></details> <details> <summary>packages/docs/guide/formulas.md (1)</summary><blockquote> `9-11`: **Optional: Add language identifier to formula code block.** Similar to other formula examples, consider adding ` ```text ` to satisfy the linter. <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@packages/docs/guide/formulas.mdaround lines 9 - 11, The code block showing
the formula "=SUM(A1:A10)" in formulas.md lacks a language identifier and fails
the linter; update the fenced code block around that formula (the block
containing =SUM(A1:A10)) to include a language tag such as "text" (i.e., open
the fence withtext and close with) so the linter accepts it.</details> </blockquote></details> <details> <summary>.github/workflows/publish-ghpage.yml (1)</summary><blockquote> `27-33`: **Prefer invoking the shared `build:all` script in CI to avoid drift.** This block duplicates root build orchestration logic; reusing one script keeps local and CI behavior aligned. <details> <summary>♻️ Proposed simplification</summary> ```diff - name: Install and Build 🔧 run: | pnpm i - pnpm frontend build - pnpm vpdocs build - rm -rf packages/frontend/dist/docs - cp -r packages/docs/.vitepress/dist packages/frontend/dist/docs + pnpm build:all ``` </details> <details> <summary>🤖 Prompt for AI Agents</summary> ``` Verify each finding against the current code and only fix it if needed. In @.github/workflows/publish-ghpage.yml around lines 27 - 33, Replace the manual multi-step install/build/copy sequence in the CI job with the shared root script: run the install then invoke the centralized build script (e.g., `pnpm i` followed by `pnpm run build:all`) instead of calling `pnpm frontend build`, `pnpm vpdocs build`, and the `rm -rf`/`cp -r` file-ops so the workflow uses the single source of truth `build:all` for orchestration. ``` </details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Inline comments:
In@docs/design/docs-site.md:
- Line 33: The three untyped fenced code blocks showing the directory trees (the
blocks starting with "packages/docs/", the ASCII box beginning
"┌─────────────────────────────────┐", and the block starting
"packages/frontend/dist/") trigger MD040; change each opening fence fromtotext so the code blocks are typed (i.e., replace the three occurrences ofwithtext and leave the closing fences as ```).In
@packages/docs/api/rest-api.md:
- Around line 27-29: The fenced code block containing the endpoint URL
"https://wafflebase.io/api/v1/workspaces/:workspaceId" lacks a language tag and
triggers MD040; update the fence to specify a language (e.g., use "text" or
"bash") so the block reads liketext ...to satisfy markdown linting and
keep the docs lint-clean.
Nitpick comments:
In @.github/workflows/publish-ghpage.yml:
- Around line 27-33: Replace the manual multi-step install/build/copy sequence
in the CI job with the shared root script: run the install then invoke the
centralized build script (e.g.,pnpm ifollowed bypnpm run build:all)
instead of callingpnpm frontend build,pnpm vpdocs build, and therm -rf/cp -rfile-ops so the workflow uses the single source of truth
build:allfor orchestration.In
@packages/docs/guide/build-a-budget.md:
- Around line 23-25: Add a language identifier to fenced code blocks containing
spreadsheet formulas (e.g., change the block containing the formula
=SUM(B2:B7)to usetext orexcel) so the linter recognizes them; scan
the file for similar formula blocks (the other instances flagged) and update
each fence to include a language specifier while keeping the formula content
unchanged.In
@packages/docs/guide/formulas.md:
- Around line 9-11: The code block showing the formula "=SUM(A1:A10)" in
formulas.md lacks a language identifier and fails the linter; update the fenced
code block around that formula (the block containing =SUM(A1:A10)) to include a
language tag such as "text" (i.e., open the fence with ```text and close withIn `@packages/frontend/scripts/capture-docs-screenshots.mjs`: - Around line 93-94: The hard-coded 500ms magic timeout in page.waitForTimeout(500) is unclear; replace the literal with a named constant (e.g. RENDER_STABILIZATION_MS) and add a short comment describing exactly what async renders or resources you're waiting for (e.g. "wait for client-side hydration / async data render to complete"), or preferably replace with a deterministic wait (e.g. page.waitForSelector or page.waitForResponse) if possible; update the call in capture-docs-screenshots.mjs where page.waitForTimeout is used to reference the new constant or deterministic wait to make the intent explicit. In `@packages/frontend/src/app/harness/docs/page.tsx`: - Around line 48-57: Refactor the promise chain that calls setup() and initialize(...) into an async/await flow: create an async function or IIFE that awaits setup() and then awaits initialize(el, { theme, store, readOnly: true, hideFormulaBar: true, hideAutofillHandle: true }), then perform the same destroyed check (call s.destroy() if destroyed), assign the result to the existing instance variable, and call setReady(true); ensure you preserve the destroyed and instance variables, keep the same call arguments (el, theme, store), and preserve error behavior (propagate or catch as the surrounding code expects). In `@packages/frontend/vite.config.ts`: - Around line 103-109: The proxy entry for "/docs" in vite.config.ts hardcodes target: "http://localhost:5174" which couples this frontend to the docs dev server port; add a concise inline comment above the proxy block referencing that 5174 must match the dev script in packages/docs/package.json (or suggest using an env var like DOCS_DEV_PORT) so future maintainers understand the dependency and how to change it.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID:
c85583d8-f5b9-4af0-8dd6-9370206ed225⛔ Files ignored due to path filters (4)
packages/docs/public/images/budget-complete.pngis excluded by!**/*.pngpackages/docs/public/images/formula-examples.pngis excluded by!**/*.pngpackages/docs/public/images/getting-started-contact-list.pngis excluded by!**/*.pngpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml📒 Files selected for processing (24)
.github/workflows/publish-ghpage.yml.gitignoredocs/design/README.mddocs/design/docs-site.mdpackage.jsonpackages/docs/.vitepress/config.tspackages/docs/.vitepress/theme/index.tspackages/docs/.vitepress/theme/style.csspackages/docs/api/cli.mdpackages/docs/api/rest-api.mdpackages/docs/guide/build-a-budget.mdpackages/docs/guide/collaboration.mdpackages/docs/guide/formulas.mdpackages/docs/guide/getting-started.mdpackages/docs/guide/keyboard-shortcuts.mdpackages/docs/index.mdpackages/docs/package.jsonpackages/frontend/package.jsonpackages/frontend/scripts/capture-docs-screenshots.mjspackages/frontend/src/App.tsxpackages/frontend/src/app/harness/docs/page.tsxpackages/frontend/src/app/home/developer-section.tsxpackages/frontend/src/app/home/nav-bar.tsxpackages/frontend/vite.config.ts
|
|
||
| ### Package Structure | ||
|
|
||
| ``` |
There was a problem hiding this comment.
Add language identifiers to fenced code blocks to satisfy markdownlint.
These fences are currently untyped and trip MD040.
🧹 Proposed fix
-```
+```text
packages/docs/
├── .vitepress/
...
-```
+```
-```
+```text
┌─────────────────────────────────┐
│ packages/frontend │
...
-```
+```
-```
+```text
packages/frontend/dist/ # ← publish_dir for GitHub Pages
├── index.html # Frontend SPA
...
-```
+```Also applies to: 92-92, 166-166
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)
[warning] 33-33: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/design/docs-site.md` at line 33, The three untyped fenced code blocks
showing the directory trees (the blocks starting with "packages/docs/", the
ASCII box beginning "┌─────────────────────────────────┐", and the block
starting "packages/frontend/dist/") trigger MD040; change each opening fence
from ``` to ```text so the code blocks are typed (i.e., replace the three
occurrences of ``` with ```text and leave the closing fences as ```).
| ``` | ||
| https://wafflebase.io/api/v1/workspaces/:workspaceId | ||
| ``` |
There was a problem hiding this comment.
Add a fence language to satisfy markdown linting.
The fenced block at Line 27 is missing a language and triggers MD040. Use text (or bash) explicitly to keep docs lint-clean.
Proposed fix
-```
+```text
https://wafflebase.io/api/v1/workspaces/:workspaceId</details>
<!-- suggestion_start -->
<details>
<summary>📝 Committable suggestion</summary>
> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
```suggestion
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)
[warning] 27-27: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/docs/api/rest-api.md` around lines 27 - 29, The fenced code block
containing the endpoint URL
"https://wafflebase.io/api/v1/workspaces/:workspaceId" lacks a language tag and
triggers MD040; update the fence to specify a language (e.g., use "text" or
"bash") so the block reads like ```text ... ``` to satisfy markdown linting and
keep the docs lint-clean.
Archive 6 task files (cross-sheet-yorkie-integration, multiline-tsv- quoting, docs-site todo/plan/lessons, cross-sheet-calc-lessons). Add docs-site and homepage design specs. Co-Authored-By: Claude Opus 4.6 <[email protected]>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
docs/design/docs-site.md (1)
33-58:⚠️ Potential issue | 🟡 MinorAdd language identifiers to the three untyped fenced blocks (MD040).
Line 33, Line 92, and Line 166 still use bare triple-backtick fences, which will keep markdownlint failing.
🧹 Proposed fix
-``` +```text packages/docs/ ├── .vitepress/ │ ├── config.ts # VitePress config (base: "/docs/") @@ └── package.json # `@wafflebase/docs` workspace@@
-+text
┌─────────────────────────────────┐
│ packages/frontend │
│ src/app/harness/docs/page.tsx │ Renders spreadsheet scenarios
@@
└─────────────────────────────────┘@@ -``` +```text packages/frontend/dist/ # ← publish_dir for GitHub Pages ├── index.html # Frontend SPA ├── 404.html # SPA fallback (spa-github-pages) @@ ├── hashmap.json # Local search index └── vp-icons.css</details> Also applies to: 92-109, 166-188 <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against the current code and only fix it if needed.
In
@docs/design/docs-site.mdaround lines 33 - 58, Update the three untyped
fenced code blocks in docs-site.md to include a language identifier (e.g.,
"text") to satisfy markdownlint MD040: addtext before the block that starts with "packages/docs/" (the workspace tree), addtext before the ASCII box
block that begins with "┌─────────────────────────────────┐" (the frontend
harness/page.tsx note), and addtext before the block that starts with "packages/frontend/dist/" (the publish_dir tree). Ensure each closing fence remainsand run markdownlint to confirm MD040 is resolved.</details> </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In@docs/design/docs-site.md:
- Around line 33-58: Update the three untyped fenced code blocks in docs-site.md
to include a language identifier (e.g., "text") to satisfy markdownlint MD040:
addtext before the block that starts with "packages/docs/" (the workspace tree), addtext before the ASCII box block that begins with
"┌─────────────────────────────────┐" (the frontend harness/page.tsx note), and
addtext before the block that starts with "packages/frontend/dist/" (the publish_dir tree). Ensure each closing fence remainsand run markdownlint to
confirm MD040 is resolved.</details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro **Run ID**: `fdeee52d-e3b3-43aa-89c4-c37d12a847d6` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 88313203a0cf7ab44a10954fb4b24b481a17beea and f72989d8b05f76dca0ce38f81610a149154b0232. </details> <details> <summary>📒 Files selected for processing (1)</summary> * `docs/design/docs-site.md` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
Add packages/docs with scenario-based user guides (getting-started, build-a-budget, collaboration, formulas, keyboard-shortcuts), REST API and CLI reference pages, and amber/gold brand theme. Product screenshots are auto-captured from a Playwright harness page that renders spreadsheets with MemStore (no backend required) and committed as static images. Build pipeline merges VitePress output into the frontend dist for single-artifact GitHub Pages deployment. Dev mode proxies /docs requests to the VitePress dev server. Also includes docs/design/docs-site.md covering architecture, screenshot pipeline, and deployment. Co-authored-by: Claude Opus 4.6 <[email protected]>
Summary
packages/docs(VitePress) with scenario-based user guides, API reference, and CLI docs/docssubpath — Vite proxy in dev, combined build artifact for GitHub Pagesdocs/design/docs-site.mdcovering architecture, screenshot pipeline, and deploymentChanges
packages/docs— VitePress site with amber/gold theme, 5 guide pages, 2 API reference pages/harness/docs) renders spreadsheets withMemStore, Playwright captures 3 scenario PNGsbuild:allscript builds frontend + docs, merges into single dist with idempotentrm -rf+cp -rpublish-ghpage.ymlto build and deploy docs alongside frontend/docs, dev proxy to VitePress serverTest plan
pnpm verify:fastpassespnpm build:allproduces correct dist structure with docs and images/docs/guide/getting-startedloads correctly after deploy/docs🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Chores
Style