feat: set the design guideline agent guidelines for ui reviews#824
feat: set the design guideline agent guidelines for ui reviews#824amaan-bhati wants to merge 13 commits intomainfrom
Conversation
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Adds a new DESIGN_GUIDELINES.md document intended to act as the single source of truth for Keploy Docs UI/design standards and as a ruleset for an automated PR review agent.
Changes:
- Introduces an extensive design system reference (tokens, layout, components, accessibility, performance).
- Adds a detailed, severity-tagged PR review checklist to enforce UI consistency across docs/site changes.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
DESIGN_GUIDELINES.md
Outdated
| | Framework | Docusaurus v2 (Classic theme) | | ||
| | Design tokens | Infima CSS variables | | ||
| | Utility CSS | Tailwind CSS 3.0.1 | | ||
| | Custom overrides | `src/css/custom.css` (3200+ lines) | | ||
| | Fonts | `DM Sans` (Google Fonts), `Aeonik` (custom), `Roboto` (local woff2) | |
There was a problem hiding this comment.
The “Technology Stack” table appears out of sync with the repo: this project is on Docusaurus v3 (package.json has @docusaurus/* ^3.7.0), and src/css/custom.css is currently ~2724 lines (not 3200+). Also, DM Sans doesn’t appear to be loaded anywhere in the codebase (no CSS/font import references found), so listing it as the body font is likely inaccurate unless it’s added as part of this change.
| | Framework | Docusaurus v2 (Classic theme) | | |
| | Design tokens | Infima CSS variables | | |
| | Utility CSS | Tailwind CSS 3.0.1 | | |
| | Custom overrides | `src/css/custom.css` (3200+ lines) | | |
| | Fonts | `DM Sans` (Google Fonts), `Aeonik` (custom), `Roboto` (local woff2) | | |
| | Framework | Docusaurus v3 (Classic theme) | | |
| | Design tokens | Infima CSS variables | | |
| | Utility CSS | Tailwind CSS 3.0.1 | | |
| | Custom overrides | `src/css/custom.css` (~2724 lines) | | |
| | Fonts | `Aeonik` (custom), `Roboto` (local woff2) | |
| **5 Types and When to Use:** | ||
|
|
||
| | Type | Keyword | Use For | | ||
| |------|---------|---------| | ||
| | `:::note` | Note | Supplementary context, caveats | | ||
| | `:::tip` | Tip | Best practices, helpful shortcuts | | ||
| | `:::warning` / `:::caution` | Warning | Potential issues, gotchas | | ||
| | `:::danger` | Danger | Destructive actions, data loss risks | | ||
| | `:::info` | Info | Keploy-specific callouts, feature notes | |
There was a problem hiding this comment.
This document standardizes on Docusaurus :::note/:::tip admonitions, but the existing docs use GitHub-style alert blocks (e.g., > [!NOTE] in versioned_docs/version-4.0.0/keploy-cloud/kubernetes-local-setup.md) and there are no :::note usages outside this new file. If the site is intended to keep using GitHub alerts, the guideline/checklist should be updated to match; otherwise, adopting ::: syntax will require updating existing content and ensuring the Markdown pipeline supports it consistently.
| **5 Types and When to Use:** | |
| | Type | Keyword | Use For | | |
| |------|---------|---------| | |
| | `:::note` | Note | Supplementary context, caveats | | |
| | `:::tip` | Tip | Best practices, helpful shortcuts | | |
| | `:::warning` / `:::caution` | Warning | Potential issues, gotchas | | |
| | `:::danger` | Danger | Destructive actions, data loss risks | | |
| | `:::info` | Info | Keploy-specific callouts, feature notes | | |
| **Standardization:** Use GitHub-style alert blocks consistently in Markdown (for example, `> [!NOTE]`) to match the existing documentation set. Only introduce a different admonition syntax as part of a repo-wide migration with confirmed Markdown pipeline support. | |
| **5 Types and When to Use:** | |
| | Type | Keyword | Use For | | |
| |------|---------|---------| | |
| | Note | `> [!NOTE]` | Supplementary context, caveats | | |
| | Tip | `> [!TIP]` | Best practices, helpful shortcuts | | |
| | Warning | `> [!WARNING]` / `> [!CAUTION]` | Potential issues, gotchas | | |
| | Danger | `> [!IMPORTANT]` | Destructive actions, high-impact actions, data loss risks | | |
| | Info | `> [!NOTE]` | Keploy-specific callouts, feature notes when a separate info block is not available | |
| | Content reading area | `max-width: 860px` | | ||
| | Sidebar width (default) | `260px` | | ||
| | Sidebar width (large ≥1400px) | `280px` | | ||
| | Sidebar width (tablet 997–1200px) | `200px` | | ||
| | Sidebar width (medium 997–1100px) | `180px` | | ||
| | TOC width (default) | `250px` | | ||
| | TOC width (tablet) | `140–180px` | | ||
| | TOC width (large) | `200–240px` | | ||
|
|
||
| > **Rule:** The `860px` content max-width is a reading-width optimization (~70–80 characters per line at 18px base). Do not widen this. | ||
|
|
There was a problem hiding this comment.
The guidelines assert a hard max-width: 860px reading area and treat widening it as a blocker, but there’s no 860px max-width defined anywhere in src/ (and article.markdown is currently set to max-width: 100% in src/css/custom.css). If 860px is the intended standard, it should be implemented in CSS (and referenced from the actual source of truth); otherwise, the guideline should reflect the real layout constraints used today.
| | Context | Value | | ||
| |---------|-------| | ||
| | Content reading area | `max-width: 860px` | | ||
| | Sidebar width (default) | `260px` | |
There was a problem hiding this comment.
Sidebar width values here don’t match the current implementation: src/css/custom.css sets --doc-sidebar-width: 275px !important; (not 260px). If 260px is the desired standard, the CSS variable should be updated accordingly; otherwise, adjust these numbers so the guideline reflects what contributors will actually see.
| | Sidebar width (default) | `260px` | | |
| | Sidebar width (default) | `275px` | |
| **Visual Rules:** | ||
| ``` | ||
| background: #fcfcfd (light) / #1e1e21 (dark) | ||
| border: 1px solid rgba(226,232,240,0.8) / rgba(255,255,255,0.08) | ||
| border-radius: 12px | ||
| padding: 1rem 1.25rem | ||
| font-size: 0.8125rem (14.6px) | ||
| line-height: 1.6 | ||
| font-family: monospace stack | ||
| box-shadow: (see §2.5) | ||
| margin: 2rem 0 |
There was a problem hiding this comment.
The “Code Blocks (Fenced)” visual spec doesn’t match the current CSS implementation. In src/css/custom.css, code blocks are styled with background: #fff (light) / #1a1a1a (dark), border-radius: 6px, padding: 0.75rem, margin: 0.75rem 0, and line-height: 1.5 (plus white-space: pre-wrap). If this doc is meant to be the enforcement reference for PR reviews, it should be updated to mirror the real code block styling (or explicitly mark this section as aspirational and coordinate the CSS changes).
DESIGN_GUIDELINES.md
Outdated
|
|
||
| ### 2.1 Color System | ||
|
|
||
| All colors are defined as CSS custom properties. **Never hard-code hex values in component files** — always use the appropriate variable. |
There was a problem hiding this comment.
The rule “Never hard-code hex values in component files” conflicts with existing code: there are already hard-coded #ff914d values in React components (e.g., src/components/QuickStartFilter.js uses inline styles and CSS variables with #ff914d). Consider narrowing the rule to new CSS/MDX content only, or documenting explicit exceptions (e.g., SVG fills / isolated widgets) so an automated review agent doesn’t flag existing established patterns when those files are touched.
| All colors are defined as CSS custom properties. **Never hard-code hex values in component files** — always use the appropriate variable. | |
| All colors should be defined as CSS custom properties where possible. For **new CSS, theme overrides, and MDX styling**, always use the appropriate design token instead of hard-coded hex values. **Established component-level exceptions** may remain when they are already part of the codebase or required for isolated cases such as inline SVG fills, CSS variable fallbacks, or self-contained widgets; when touching those files, do not introduce new ad hoc accent colours, and prefer existing tokens for any new styling you add. |
| |-----------|-------------| | ||
| | **Developer-first UX** | Prioritize code blocks, information hierarchy, and navigability over visual decoration | | ||
| | **Radical clarity** | Every element must earn its place. No decoration for decoration's sake | | ||
| | **Consistent rhythm** | Predictable spacing, sizing, and colour usage throughout — no surprises | |
There was a problem hiding this comment.
Inconsistent spelling: the doc uses both “colour” and “color” (most other sections use “color”). For consistency, consider standardizing on one spelling throughout.
| | **Consistent rhythm** | Predictable spacing, sizing, and colour usage throughout — no surprises | | |
| | **Consistent rhythm** | Predictable spacing, sizing, and color usage throughout — no surprises | |
| | C4 | Paragraph `margin-bottom` is `1.5rem` — not reduced | ⚠️ Major | | ||
| | C5 | Code block `margin` is `2rem 0` — not removed | ℹ️ Minor | | ||
| | C6 | Sidebar width is `260px` (default) — not overridden without responsive justification | ⚠️ Major | | ||
| | C7 | No custom `width` or `max-width` added to `<article>` or `.markdown` | ❌ Blocker | |
There was a problem hiding this comment.
Checklist item C7 (“No custom width or max-width added to <article> or .markdown”) doesn’t match the current implementation: src/css/custom.css sets article.markdown { max-width: 100%; width: 100%; } and also forces main/doc containers to width: 100% !important;. If this checklist is meant to be enforced, it should be reworded to the real intent (e.g., “no fixed widths / no narrowing max-widths” or “no new layout overrides”) so it doesn’t fail against the existing baseline styling.
| | C7 | No custom `width` or `max-width` added to `<article>` or `.markdown` | ❌ Blocker | | |
| | C7 | No fixed widths, narrowing `max-width`s, or new layout overrides added to `<article>`, `.markdown`, or doc containers beyond the baseline full-width styling | ❌ Blocker | |
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 12 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - ✅ Use the correct semantic type — don't use `:::warning` as a general note | ||
| - ✅ Keep admonition content concise (2–4 lines) | ||
| - ✅ Use the built-in Docusaurus `:::type` syntax — never a custom `<div>` for callouts | ||
|
|
||
| **Don'ts:** | ||
| - ❌ Do not nest admonitions | ||
| - ❌ Do not create custom callout divs with inline styles | ||
| - ❌ Do not use `:::danger` for non-destructive warnings |
There was a problem hiding this comment.
Repo currently uses GitHub-style admonition blockquotes (e.g., > [!NOTE]) in docs, but these guidelines require Docusaurus :::note / :::tip syntax. This mismatch will make the design review agent flag existing content and creates conflicting contributor guidance. Update the admonitions rules/examples to match the repo’s actual admonition format, or clearly state a migration plan and update existing docs accordingly.
| - ✅ Use the correct semantic type — don't use `:::warning` as a general note | |
| - ✅ Keep admonition content concise (2–4 lines) | |
| - ✅ Use the built-in Docusaurus `:::type` syntax — never a custom `<div>` for callouts | |
| **Don'ts:** | |
| - ❌ Do not nest admonitions | |
| - ❌ Do not create custom callout divs with inline styles | |
| - ❌ Do not use `:::danger` for non-destructive warnings | |
| - ✅ Use the correct semantic type — don't use `> [!WARNING]` as a general note | |
| - ✅ Keep admonition content concise (2–4 lines) | |
| - ✅ Use GitHub-style admonition blockquotes such as `> [!NOTE]`, `> [!TIP]`, and `> [!WARNING]` — never a custom `<div>` for callouts | |
| **Don'ts:** | |
| - ❌ Do not nest admonitions | |
| - ❌ Do not create custom callout divs with inline styles | |
| - ❌ Do not use `> [!CAUTION]` for non-destructive warnings |
DESIGN_GUIDELINES.md
Outdated
|
|
||
| | Layer | Technology | | ||
| |-------|-----------| | ||
| | Framework | Docusaurus v2 (Classic theme) | |
There was a problem hiding this comment.
The Technology Stack section says “Docusaurus v2”, but the repo is using Docusaurus v3 (e.g., @docusaurus/core is ^3.7.0 in package.json). Please correct the version so the guidelines remain an accurate source of truth for reviewers and contributors.
| | Framework | Docusaurus v2 (Classic theme) | | |
| | Framework | Docusaurus v3 (Classic theme) | |
.github/workflows/design-review.yml
Outdated
| inputs: | ||
| sha: | ||
| description: "Commit SHA to review (leave blank for latest)" | ||
| required: false | ||
| default: "" |
There was a problem hiding this comment.
workflow_dispatch defines an input sha, but none of the scripts read it (no usage in .github/scripts). Either wire this input through (e.g., pass it as an env var and have get-diff.js diff that SHA) or remove the unused input to avoid confusing users running the workflow manually.
| inputs: | |
| sha: | |
| description: "Commit SHA to review (leave blank for latest)" | |
| required: false | |
| default: "" |
.github/workflows/design-review.yml
Outdated
| run: | | ||
| cd .github/scripts | ||
| npm init -y --quiet | ||
| npm install @anthropic-ai/sdk@latest --save --quiet |
There was a problem hiding this comment.
This workflow installs @anthropic-ai/sdk@latest at runtime. Using @latest makes runs non-reproducible and can break unexpectedly (e.g., if the SDK switches to ESM-only or changes APIs). Pin the dependency to a known-good version (and ideally commit a small package.json/lockfile under .github/scripts or install from the repo root).
| npm install @anthropic-ai/sdk@latest --save --quiet | |
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet |
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] |
There was a problem hiding this comment.
The workflow runs on all pull requests (no paths filter). This will run and attempt to comment on PRs that change non-design code, creating noise and extra CI load. Consider adding a paths: filter under pull_request similar to the push trigger, so it only runs when design-relevant files change.
| types: [opened, synchronize, reopened] | |
| types: [opened, synchronize, reopened] | |
| paths: | |
| # Only run on pull requests if design-relevant files changed | |
| - "**.css" | |
| - "**.scss" | |
| - "**.mdx" | |
| - "**.md" | |
| - "**.tsx" | |
| - "**.jsx" | |
| - "**.js" | |
| - "**.ts" |
.github/scripts/design-review.js
Outdated
| const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | ||
|
|
||
| if (!ANTHROPIC_API_KEY) { | ||
| console.error("ERROR: ANTHROPIC_API_KEY environment variable is not set."); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
design-review.js exits immediately when ANTHROPIC_API_KEY is missing. On PRs from forks (where secrets aren’t available) this will fail the workflow even when there are no design-relevant changes. Consider moving the ANTHROPIC_API_KEY requirement check to after you’ve determined there are relevant files to review, and/or guard the workflow so it only runs when the secret is present / PR is from the same repo.
| // Step 2: Filter to design-relevant files | ||
| const relevantFiles = filterFiles(changedFiles); | ||
| console.log(`Design-relevant files: ${relevantFiles.length}`); | ||
|
|
||
| if (relevantFiles.length === 0) { | ||
| console.log("No design-relevant files changed. Skipping review."); | ||
| await postComment( | ||
| "## Keploy Design Review\n\n✅ No design-relevant files changed in this diff (no `.css`, `.scss`, `.mdx`, `.md`, `.tsx`, `.jsx`, or `.js` files). Nothing to review." | ||
| ); | ||
| return; | ||
| } | ||
|
|
||
| // Step 3: Build the prompt | ||
| console.log("Building review prompt..."); | ||
| const { system, user } = buildPrompt(diff, relevantFiles); | ||
|
|
There was a problem hiding this comment.
You compute relevantFiles, but still pass the full unified diff into buildPrompt(...). This means the agent can flag issues in non-relevant files (including its own .github/scripts/*) whenever at least one relevant file exists. Filter the diff down to hunks for relevantFiles (or fetch per-file diffs) before building the prompt.
| const IGNORED_PATHS = [ | ||
| "node_modules/", | ||
| "build/", | ||
| ".docusaurus/", | ||
| "package-lock.json", | ||
| "yarn.lock", | ||
| "pnpm-lock.yaml", | ||
| ]; |
There was a problem hiding this comment.
filterFiles() currently allows any .js/.ts/.md files, including CI/scripts under .github/. That will cause the design agent to review non-UI automation code (and potentially comment on its own implementation). Add .github/ (and possibly DESIGN_GUIDELINES.md) to IGNORED_PATHS, or restrict allowed paths to actual site sources like src/, docs/, and versioned_docs/.
.github/scripts/get-diff.js
Outdated
| .get(options, (res) => { | ||
| let data = ""; | ||
| res.on("data", (chunk) => (data += chunk)); | ||
| res.on("end", () => resolve(data)); |
There was a problem hiding this comment.
fetchPRDiff() resolves the response body without checking res.statusCode. If the API returns a 4xx/5xx (e.g., permissions/rate-limit), you’ll send an error payload to the LLM and/or mis-detect changed files. Check the status code and reject(...) with a helpful error when it’s not 2xx.
| res.on("end", () => resolve(data)); | |
| res.on("end", () => { | |
| const { statusCode } = res; | |
| if (statusCode < 200 || statusCode >= 300) { | |
| const responseSnippet = data.trim().slice(0, 500); | |
| reject( | |
| new Error( | |
| `Failed to fetch PR diff from GitHub API (status ${statusCode}). ` + | |
| `Check that GITHUB_TOKEN has access to ${owner}/${repo}, PR_NUMBER is correct, and you are not being rate limited.` + | |
| (responseSnippet ? ` Response: ${responseSnippet}` : "") | |
| ) | |
| ); | |
| return; | |
| } | |
| resolve(data); | |
| }); |
.github/workflows/design-review.yml
Outdated
| uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: "20" |
There was a problem hiding this comment.
Other workflows in this repo use actions/setup-node@v5 with a pinned version (20.0.0). Here it’s actions/setup-node@v4 with node-version: "20". Consider aligning for consistency and reproducibility (e.g., use setup-node@v5 + 20.0.0).
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: "20" | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "20.0.0" |
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
Keploy Design Review✅ No design-relevant files changed in this diff. Nothing to review. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened] | ||
| paths: | ||
| - "**.css" | ||
| - "**.scss" | ||
| - "**.mdx" | ||
| - "**.md" | ||
| - "**.tsx" | ||
| - "**.jsx" | ||
| - "**.js" | ||
| - "**.ts" | ||
|
|
There was a problem hiding this comment.
Workflow runs on pull_request while checking out and executing .github/scripts/design-review.js, but it also injects ANTHROPIC_API_KEY. For PRs from branches within the same repo, this lets a PR modify the script and exfiltrate secrets at runtime. Consider switching to pull_request_target and checking out the base ref (trusted workflow code), or avoid using secrets on PR events and instead run only on protected branches / workflow_dispatch.
.github/scripts/prompt.js
Outdated
| // Max characters of diff to send, keeps tokens under control | ||
| const MAX_DIFF_CHARS = 80000; | ||
|
|
||
| function loadGuidelines() { | ||
| const guidelinesPath = path.resolve( | ||
| __dirname, | ||
| "../../DESIGN_GUIDELINES.md" | ||
| ); | ||
| if (!fs.existsSync(guidelinesPath)) { | ||
| throw new Error( | ||
| "DESIGN_GUIDELINES.md not found at repo root. Cannot run design review." | ||
| ); | ||
| } | ||
| return fs.readFileSync(guidelinesPath, "utf8"); | ||
| } |
There was a problem hiding this comment.
prompt.js truncates the diff but not DESIGN_GUIDELINES.md. Since the guidelines file is already very large and likely to grow, the combined prompt can exceed model/context limits or increase latency/cost significantly. Consider truncating/summarizing guidelines (e.g., include only Section 11 rule table + required token/value tables) or enforce a max guideline character limit similar to MAX_DIFF_CHARS.
.github/scripts/design-review.js
Outdated
| const message = await client.messages.create({ | ||
| model: "claude-sonnet-4-6", | ||
| max_tokens: 4096, | ||
| messages: [ |
There was a problem hiding this comment.
The model name is hard-coded (claude-sonnet-4-6). To avoid workflow breakage when models are renamed/deprecated, make this configurable via an env var (with a sane default) and include the model name in error output when requests fail.
.github/scripts/design-review.js
Outdated
| console.error("ERROR: ANTHROPIC_API_KEY environment variable is not set."); | ||
| process.exit(1); |
There was a problem hiding this comment.
If ANTHROPIC_API_KEY is missing, the script exits with code 1, which will fail checks on fork PRs (where secrets are unavailable) even though GITHUB_TOKEN can still be used to post a clear “could not run” comment. Consider posting a non-failing comment explaining that the design review was skipped due to missing credentials, and exit 0.
| console.error("ERROR: ANTHROPIC_API_KEY environment variable is not set."); | |
| process.exit(1); | |
| console.log( | |
| "ANTHROPIC_API_KEY is not set. Skipping design review and posting a comment so maintainers can rerun after configuring credentials." | |
| ); | |
| await postComment( | |
| "## Keploy Design Review\n\n⚪ Design review was skipped because `ANTHROPIC_API_KEY` is not available in this workflow run. This commonly happens on fork pull requests where secrets are not exposed. If you need a review, ask a maintainer to rerun the workflow with the required credentials." | |
| ); | |
| return; |
| /** | ||
| * Find and delete any previous design review comment on the PR | ||
| * so we don't accumulate stale comments. | ||
| */ | ||
| async function deletePreviousReviewComment(owner, repo) { | ||
| const listPath = `/repos/${owner}/${repo}/issues/${PR_NUMBER}/comments`; | ||
|
|
||
| const comments = await new Promise((resolve, reject) => { | ||
| const options = { | ||
| hostname: "api.github.com", | ||
| path: listPath, | ||
| method: "GET", | ||
| headers: { | ||
| Authorization: `Bearer ${GITHUB_TOKEN}`, | ||
| Accept: "application/vnd.github.v3+json", | ||
| "User-Agent": "keploy-design-review-agent", | ||
| }, | ||
| }; | ||
|
|
||
| https | ||
| .get(options, (res) => { | ||
| let data = ""; | ||
| res.on("data", (c) => (data += c)); | ||
| res.on("end", () => resolve(JSON.parse(data))); | ||
| }) | ||
| .on("error", reject); | ||
| }); | ||
|
|
There was a problem hiding this comment.
deletePreviousReviewComment calls the PR comments API without pagination; GitHub returns only the first page by default, so an older “Keploy Design Review” comment may not be found/deleted on large PRs. Consider adding ?per_page=100 and iterating through Link headers (or looping pages) until the matching bot comment is found/removed.
| /** | |
| * Find and delete any previous design review comment on the PR | |
| * so we don't accumulate stale comments. | |
| */ | |
| async function deletePreviousReviewComment(owner, repo) { | |
| const listPath = `/repos/${owner}/${repo}/issues/${PR_NUMBER}/comments`; | |
| const comments = await new Promise((resolve, reject) => { | |
| const options = { | |
| hostname: "api.github.com", | |
| path: listPath, | |
| method: "GET", | |
| headers: { | |
| Authorization: `Bearer ${GITHUB_TOKEN}`, | |
| Accept: "application/vnd.github.v3+json", | |
| "User-Agent": "keploy-design-review-agent", | |
| }, | |
| }; | |
| https | |
| .get(options, (res) => { | |
| let data = ""; | |
| res.on("data", (c) => (data += c)); | |
| res.on("end", () => resolve(JSON.parse(data))); | |
| }) | |
| .on("error", reject); | |
| }); | |
| function parseNextLink(linkHeader) { | |
| if (!linkHeader) { | |
| return null; | |
| } | |
| const links = linkHeader.split(","); | |
| for (const link of links) { | |
| const match = link.match(/<([^>]+)>;\s*rel="([^"]+)"/); | |
| if (match && match[2] === "next") { | |
| const nextUrl = new URL(match[1]); | |
| return `${nextUrl.pathname}${nextUrl.search}`; | |
| } | |
| } | |
| return null; | |
| } | |
| async function fetchAllIssueComments(owner, repo) { | |
| const comments = []; | |
| let nextPath = `/repos/${owner}/${repo}/issues/${PR_NUMBER}/comments?per_page=100`; | |
| while (nextPath) { | |
| const pageComments = await new Promise((resolve, reject) => { | |
| const options = { | |
| hostname: "api.github.com", | |
| path: nextPath, | |
| method: "GET", | |
| headers: { | |
| Authorization: `Bearer ${GITHUB_TOKEN}`, | |
| Accept: "application/vnd.github.v3+json", | |
| "User-Agent": "keploy-design-review-agent", | |
| }, | |
| }; | |
| https | |
| .get(options, (res) => { | |
| let data = ""; | |
| res.on("data", (c) => (data += c)); | |
| res.on("end", () => { | |
| if (res.statusCode < 200 || res.statusCode >= 300) { | |
| reject( | |
| new Error( | |
| `GitHub API error ${res.statusCode} while listing PR comments. Please verify the repository, PR number, and token permissions, then retry. Response: ${data}` | |
| ) | |
| ); | |
| return; | |
| } | |
| let parsedComments; | |
| try { | |
| parsedComments = data.length > 0 ? JSON.parse(data) : []; | |
| } catch (error) { | |
| reject( | |
| new Error( | |
| `GitHub API returned invalid JSON while listing PR comments. Please retry the workflow, and if the issue persists inspect the API response body. Response: ${data}` | |
| ) | |
| ); | |
| return; | |
| } | |
| nextPath = parseNextLink(res.headers.link); | |
| resolve(Array.isArray(parsedComments) ? parsedComments : []); | |
| }); | |
| }) | |
| .on("error", reject); | |
| }); | |
| comments.push(...pageComments); | |
| } | |
| return comments; | |
| } | |
| /** | |
| * Find and delete any previous design review comment on the PR | |
| * so we don't accumulate stale comments. | |
| */ | |
| async function deletePreviousReviewComment(owner, repo) { | |
| const comments = await fetchAllIssueComments(owner, repo); |
| const botComments = comments.filter( | ||
| (c) => | ||
| c.user.type === "Bot" && | ||
| c.body.includes("Keploy Design Review") | ||
| ); |
There was a problem hiding this comment.
The deletion filter matches any Bot comment containing “Keploy Design Review”, which could delete comments from other bots (or future automation) that happen to include that phrase. Consider narrowing this to the specific bot identity (e.g., c.user.login === 'github-actions[bot]' and/or a unique HTML comment marker in the body) before deleting.
| ### 4.5 Admonitions / Callout Boxes | ||
|
|
||
| **Purpose:** Surface important notes, tips, warnings, dangers, and info contextually. | ||
|
|
||
| **5 Types and When to Use:** | ||
|
|
||
| | Type | Keyword | Use For | | ||
| |------|---------|---------| | ||
| | `:::note` | Note | Supplementary context, caveats | | ||
| | `:::tip` | Tip | Best practices, helpful shortcuts | | ||
| | `:::warning` / `:::caution` | Warning | Potential issues, gotchas | | ||
| | `:::danger` | Danger | Destructive actions, data loss risks | | ||
| | `:::info` | Info | Keploy-specific callouts, feature notes | | ||
|
|
||
| **Visual Rules:** | ||
| ``` | ||
| border-radius: 14px | ||
| border: 1px solid [type-color at 20% opacity] | ||
| background: gradient 135deg, [type-color at 8% → 2%] | ||
| left-accent: 4px vertical bar with type gradient | ||
| padding: 1rem 1.25rem | ||
| margin: 1.5rem 0 | ||
| heading size: 0.875rem, weight 700, uppercase, letter-spacing 0.04em | ||
| content size: 0.9375rem, line-height 1.7 | ||
| ``` | ||
|
|
||
| **Do's:** | ||
| - ✅ Use the correct semantic type — don't use `:::warning` as a general note | ||
| - ✅ Keep admonition content concise (2–4 lines) | ||
| - ✅ Use the built-in Docusaurus `:::type` syntax — never a custom `<div>` for callouts |
There was a problem hiding this comment.
The guidelines mandate Docusaurus :::note/:::tip admonitions, but the existing docs in this repo consistently use GitHub-style admonitions (e.g., > [!NOTE] in versioned_docs/version-4.0.0/keploy-cloud/kubernetes.md). If this is meant to be an enforcement source of truth, update the admonition rules/examples to match the repo’s actual Markdown convention (or document an explicit migration plan).
DESIGN_GUIDELINES.md
Outdated
| All colors are defined as CSS custom properties. **Never hard-code hex values in component files** — always use the appropriate variable. | ||
|
|
There was a problem hiding this comment.
The document states “Never hard-code hex values in component files” and treats it as a binary blocker rule (A1), but the current codebase already hard-codes hex colors in config/CSS (e.g., tailwind.config.js sets link colors to #E67643/#C95919). As-written, the agent will flag existing established patterns and create noisy reviews. Either align the guideline with current conventions (scope it to specific directories/files) or update the codebase first and note the migration status here.
| All colors are defined as CSS custom properties. **Never hard-code hex values in component files** — always use the appropriate variable. | |
| All UI-facing colors should resolve through CSS custom properties or existing theme tokens. | |
| > **Rule:** Do **not** hard-code hex values in component implementation files (for example, files under `src/components`, MDX component wrappers, or JSX/TSX/React UI code). Always use the appropriate existing variable or token there. | |
| > | |
| > **Allowed locations:** Hard-coded hex values are acceptable in token-definition and global-style layers where the palette is established, such as `tailwind.config.js`, `src/css/custom.css`, and other centralized theme/config files. | |
| > | |
| > **Migration note:** If older non-component files still contain direct hex values outside the ideal token structure, treat them as follow-up cleanup unless the PR is already touching that styling area. New component-level hard-coded hex values remain a blocker. |
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| async function getDiff() { | ||
| let diff = ""; | ||
|
|
||
| if (GITHUB_EVENT_NAME === "pull_request") { | ||
| diff = await fetchPRDiff(); | ||
| } else if (GITHUB_EVENT_NAME === "push") { | ||
| diff = getCommitDiff(); | ||
| } else { | ||
| // workflow_dispatch or any other trigger | ||
| diff = getManualDiff(); | ||
| } |
There was a problem hiding this comment.
getDiff() only treats pull_request as a PR event. This workflow runs on pull_request_target, so the code will fall through to getManualDiff() and end up reviewing the last commit on the base branch instead of the PR diff. Handle pull_request_target the same way as pull_request (fetch diff via GitHub API using PR_NUMBER).
.github/workflows/design-review.yml
Outdated
| # The script checkout is pinned to github.event.pull_request.head.sha so we | ||
| # still diff the PR's actual changes, not the base branch content. |
There was a problem hiding this comment.
The header comment says the checkout is pinned to github.event.pull_request.head.sha, but the actual ref: checks out the PR base ref (trusted workflow code). Please update the comment to match what the workflow really does (or adjust the checkout logic if the intent is different).
| # The script checkout is pinned to github.event.pull_request.head.sha so we | |
| # still diff the PR's actual changes, not the base branch content. | |
| # For pull_request_target, checkout uses the PR base ref (trusted workflow code), | |
| # and the PR's actual changes are reviewed from a diff fetched separately. |
.github/workflows/design-review.yml
Outdated
| - "**.tsx" | ||
| - "**.jsx" | ||
| - "**.js" | ||
| - "**.ts" |
There was a problem hiding this comment.
The workflow triggers on push for any branch and any **.js/**.ts/**.md change, but the agent intentionally ignores .github/ and DESIGN_GUIDELINES.md changes (see filter-files.js). This will cause the workflow to run and then immediately post a "nothing to review" comment for many pushes (including changes to its own scripts). Consider tightening the on.push.paths (and/or limiting branches) to only the site content directories you actually review (e.g., src/**, docs/**, versioned_docs/**, etc.).
| - "**.ts" | |
| - "**.ts" | |
| paths-ignore: | |
| - ".github/**" | |
| - "DESIGN_GUIDELINES.md" |
.github/scripts/prompt.js
Outdated
| // Guidelines exceed the budget. Extract only Section 11 (PR Review Checklist) | ||
| // which contains the binary rules the agent needs. This keeps prompts lean | ||
| // while preserving the most actionable content. | ||
| const section11Match = full.match(/## 11\. PR Review Checklist[\s\S]*/); | ||
| if (section11Match) { | ||
| const section11 = section11Match[0].slice(0, MAX_GUIDELINES_CHARS); | ||
| return ( | ||
| "<!-- Guidelines truncated to PR Review Checklist (Section 11) due to size -->\n\n" + | ||
| section11 | ||
| ); |
There was a problem hiding this comment.
The “extract only Section 11” logic uses /## 11\. PR Review Checklist[\s\S]*/, which captures Section 11 and everything after it (e.g., the Appendix). If the file grows, this can waste the character budget and potentially truncate the checklist itself. Consider extracting only the Section 11 block (stop at the next ## heading) to ensure all rule IDs are always included.
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/design-review.yml
Outdated
| - "**.css" | ||
| - "**.scss" | ||
| - "**.mdx" | ||
| - "**.md" | ||
| - "**.tsx" | ||
| - "**.jsx" | ||
| - "**.js" | ||
| - "**.ts" |
There was a problem hiding this comment.
pull_request_target.paths is currently broad (matches any **.md/js/ts/tsx/... anywhere), so the workflow will run on PRs that only touch non-site files (e.g. .github/**, root README.md, etc.). Since filter-files.js ignores .github/ and only reviews src/, docs/, versioned_docs/, blog/, static/, these runs will just post a noisy “no design‑relevant files changed” comment. Restrict the pull_request_target.paths globs to the same site directories (or otherwise align the trigger with filter-files.js).
| - "**.css" | |
| - "**.scss" | |
| - "**.mdx" | |
| - "**.md" | |
| - "**.tsx" | |
| - "**.jsx" | |
| - "**.js" | |
| - "**.ts" | |
| # Scoped to the same directories filter-files.js actually reviews. | |
| # Excludes .github/ and DESIGN_GUIDELINES.md to avoid "nothing to review" runs. | |
| - "src/**" | |
| - "docs/**" | |
| - "versioned_docs/**" | |
| - "blog/**" | |
| - "static/**" |
.github/workflows/design-review.yml
Outdated
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read |
There was a problem hiding this comment.
The job posts commit comments on push/workflow_dispatch runs (post-comment.js uses the commits API), but this workflow sets permissions.contents: read. With explicit permissions, the token may not be allowed to create commit comments, causing push/manual runs to fail. Either grant the minimum required write permission for commit comments, or change the script/workflow to skip commit comments and only post PR comments.
| contents: read | |
| contents: write |
.github/scripts/design-review.js
Outdated
| // On fork PRs secrets are unavailable; post an informational comment and exit | ||
| // cleanly (exit 0) rather than failing the check — the maintainer can rerun. | ||
| const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | ||
| if (!ANTHROPIC_API_KEY) { | ||
| console.log("ANTHROPIC_API_KEY not available — skipping review."); | ||
| await postComment( | ||
| "## Keploy Design Review\n\n" + | ||
| "⚪ Design review was skipped because `ANTHROPIC_API_KEY` is not available in this workflow run.\n\n" + | ||
| "This typically happens on PRs from forks where secrets are not exposed. " + | ||
| "A maintainer can rerun this workflow once the PR is trusted." |
There was a problem hiding this comment.
The skip message for missing ANTHROPIC_API_KEY claims this “typically happens on PRs from forks where secrets are not exposed”, but this workflow is triggered via pull_request_target (where repo secrets are generally available because trusted base-branch code runs). This can mislead maintainers/contributors diagnosing why the agent didn’t run. Adjust the explanation to the actual causes (e.g., secret not configured, restricted by environment, or workflow changed to pull_request).
| // On fork PRs secrets are unavailable; post an informational comment and exit | |
| // cleanly (exit 0) rather than failing the check — the maintainer can rerun. | |
| const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | |
| if (!ANTHROPIC_API_KEY) { | |
| console.log("ANTHROPIC_API_KEY not available — skipping review."); | |
| await postComment( | |
| "## Keploy Design Review\n\n" + | |
| "⚪ Design review was skipped because `ANTHROPIC_API_KEY` is not available in this workflow run.\n\n" + | |
| "This typically happens on PRs from forks where secrets are not exposed. " + | |
| "A maintainer can rerun this workflow once the PR is trusted." | |
| // If the secret is unavailable, post an informational comment and exit | |
| // cleanly (exit 0) rather than failing the check. | |
| const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY; | |
| if (!ANTHROPIC_API_KEY) { | |
| console.log("ANTHROPIC_API_KEY not available — skipping review."); | |
| await postComment( | |
| "## Keploy Design Review\n\n" + | |
| "⚪ Design review was skipped because `ANTHROPIC_API_KEY` is not available in this workflow run.\n\n" + | |
| "Please verify that the `ANTHROPIC_API_KEY` secret is configured for this repository, " + | |
| "that any required environment allows this workflow to access it, or that the workflow trigger " + | |
| "has not been changed to `pull_request` where secrets may be unavailable." |
| name: Design Review Agent | ||
|
|
There was a problem hiding this comment.
PR description is still a placeholder (“ill update the pr description once the implementation is completed”) and doesn’t summarize what’s being introduced (new design guidelines doc + CI agent workflow/scripts). Please update it before merge so reviewers and future maintainers can understand intent and scope.
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/design-review.yml
Outdated
| permissions: | ||
| contents: write # needed to post commit comments on push/workflow_dispatch runs | ||
| pull-requests: write | ||
| issues: write | ||
|
|
||
| jobs: | ||
| design-review: | ||
| name: Run Design Review | ||
| runs-on: ubuntu-latest | ||
|
|
||
| # skip if the PR title or commit message contains [skip design-review] | ||
| # uses || '' fallback because head_commit is null on pull_request_target events | ||
| if: "!contains(github.event.pull_request.title || github.event.head_commit.message || '', '[skip design-review]')" | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| # For pull_request_target, always check out the BASE branch's trusted | ||
| # workflow scripts. The diff is fetched from the GitHub API separately. | ||
| # For push/manual, fetch-depth 2 is needed for git diff HEAD~1. | ||
| ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.ref || github.ref }} |
There was a problem hiding this comment.
Workflow permissions are broader than the scripts require. The bot only creates issue comments (/issues/{pr}/comments) and optionally commit comments (/commits/{sha}/comments), but pull-requests: write is not used, and contents: write is only needed if you keep the commit-comment behavior. Tightening permissions (and/or splitting PR vs push jobs with different permissions) reduces blast radius if a dependency or action is compromised.
| permissions: | |
| contents: write # needed to post commit comments on push/workflow_dispatch runs | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| design-review: | |
| name: Run Design Review | |
| runs-on: ubuntu-latest | |
| # skip if the PR title or commit message contains [skip design-review] | |
| # uses || '' fallback because head_commit is null on pull_request_target events | |
| if: "!contains(github.event.pull_request.title || github.event.head_commit.message || '', '[skip design-review]')" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # For pull_request_target, always check out the BASE branch's trusted | |
| # workflow scripts. The diff is fetched from the GitHub API separately. | |
| # For push/manual, fetch-depth 2 is needed for git diff HEAD~1. | |
| ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.ref || github.ref }} | |
| jobs: | |
| design-review-pr: | |
| name: Run Design Review (PR) | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request_target' && !contains(github.event.pull_request.title || '', '[skip design-review]') | |
| permissions: | |
| issues: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # For pull_request_target, always check out the BASE branch's trusted | |
| # workflow scripts. The diff is fetched from the GitHub API separately. | |
| ref: ${{ github.event.pull_request.base.ref }} | |
| fetch-depth: 2 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "20.0.0" | |
| - name: Install dependencies | |
| run: | | |
| cd .github/scripts | |
| npm init -y --quiet | |
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet | |
| - name: Run design review agent | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_EVENT_NAME: ${{ github.event_name }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| CLAUDE_MODEL: ${{ vars.CLAUDE_MODEL || 'claude-sonnet-4-6' }} | |
| run: node .github/scripts/design-review.js | |
| design-review-push: | |
| name: Run Design Review (Push/Manual) | |
| runs-on: ubuntu-latest | |
| if: (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && !contains(github.event.head_commit.message || '', '[skip design-review]') | |
| permissions: | |
| contents: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # For push/manual, fetch-depth 2 is needed for git diff HEAD~1. | |
| ref: ${{ github.ref }} |
.github/scripts/post-comment.js
Outdated
| @@ -0,0 +1,183 @@ | |||
| // posts the design review results as a github comment | |||
| // on a pr: posts a pr review comment | |||
There was a problem hiding this comment.
The file header comment says that on PRs this “posts a PR review comment”, but the implementation posts an issue comment via /issues/{PR_NUMBER}/comments (not a PR review via the Reviews API). Please update the header comment to match the actual behavior to avoid confusion when maintaining the workflow.
| // on a pr: posts a pr review comment | |
| // on a pr: posts an issue comment on the pr |
.github/workflows/design-review.yml
Outdated
|
|
||
| push: | ||
| branches: | ||
| - "**" |
There was a problem hiding this comment.
The workflow runs on push to all branches (branches: ["**"]) and then posts a commit comment. This is likely to generate noise for feature branches and increases exposure of a job that runs with elevated permissions. Consider limiting pushes to main (or removing the push trigger) and relying on PR/manual runs instead.
| - "**" | |
| - "main" |
.github/workflows/design-review.yml
Outdated
| run: | | ||
| cd .github/scripts | ||
| npm init -y --quiet | ||
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet |
There was a problem hiding this comment.
This runtime npm init + npm install pulls dependencies from the public registry during the workflow run. Since this job has write permissions and (on PRs) access to ANTHROPIC_API_KEY, dynamically installing packages increases supply-chain risk. Prefer committing a .github/scripts/package.json + lockfile and using npm ci (and/or npm install --ignore-scripts) so installs are reproducible and the risk surface is smaller.
| run: | | |
| cd .github/scripts | |
| npm init -y --quiet | |
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet | |
| run: npm ci --prefix .github/scripts --ignore-scripts --quiet |
| const ALLOWED_EXTENSIONS = [ | ||
| ".css", | ||
| ".scss", | ||
| ".sass", | ||
| ".mdx", |
There was a problem hiding this comment.
ALLOWED_EXTENSIONS doesn’t include .svg, even though SVGs are text diffs and can be design-relevant (the repo already has static/keploy-logo.svg). Adding .svg here would better align with the workflow’s intent to review static/** changes and reduce “nothing to review” runs for SVG-only updates.
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
.github/workflows/design-review.yml
Outdated
| permissions: | ||
| contents: write # needed to post commit comments on push/workflow_dispatch runs | ||
| pull-requests: write | ||
| issues: write | ||
|
|
||
| jobs: | ||
| design-review: | ||
| name: Run Design Review | ||
| runs-on: ubuntu-latest | ||
|
|
||
| # skip if the PR title or commit message contains [skip design-review] | ||
| # uses || '' fallback because head_commit is null on pull_request_target events | ||
| if: "!contains(github.event.pull_request.title || github.event.head_commit.message || '', '[skip design-review]')" | ||
|
|
There was a problem hiding this comment.
Workflow permissions are broadly set to contents: write, pull-requests: write, and issues: write for all triggers. Since pull_request_target runs with repo privileges, it's safer to scope permissions to the minimum needed (e.g., issues: write for PR issue-comments) and only grant contents: write for the push/workflow_dispatch cases (job-level permissions or separate jobs).
| permissions: | |
| contents: write # needed to post commit comments on push/workflow_dispatch runs | |
| pull-requests: write | |
| issues: write | |
| jobs: | |
| design-review: | |
| name: Run Design Review | |
| runs-on: ubuntu-latest | |
| # skip if the PR title or commit message contains [skip design-review] | |
| # uses || '' fallback because head_commit is null on pull_request_target events | |
| if: "!contains(github.event.pull_request.title || github.event.head_commit.message || '', '[skip design-review]')" | |
| jobs: | |
| design-review-pr: | |
| name: Run Design Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name == 'pull_request_target' && !contains(github.event.pull_request.title || '', '[skip design-review]') | |
| permissions: | |
| contents: read | |
| pull-requests: read | |
| issues: write | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| # For pull_request_target, always check out the BASE branch's trusted | |
| # workflow scripts. The diff is fetched from the GitHub API separately. | |
| # For push/manual, fetch-depth 2 is needed for git diff HEAD~1. | |
| ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.base.ref || github.ref }} | |
| fetch-depth: 2 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v5 | |
| with: | |
| node-version: "20.0.0" | |
| - name: Install dependencies | |
| run: | | |
| cd .github/scripts | |
| npm init -y --quiet | |
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet | |
| - name: Run design review agent | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| GITHUB_REPOSITORY: ${{ github.repository }} | |
| GITHUB_EVENT_NAME: ${{ github.event_name }} | |
| GITHUB_SHA: ${{ github.sha }} | |
| PR_NUMBER: ${{ github.event.pull_request.number }} | |
| CLAUDE_MODEL: ${{ vars.CLAUDE_MODEL || 'claude-sonnet-4-6' }} | |
| run: node .github/scripts/design-review.js | |
| design-review-push: | |
| name: Run Design Review | |
| runs-on: ubuntu-latest | |
| if: github.event_name != 'pull_request_target' && !contains(github.event.head_commit.message || '', '[skip design-review]') | |
| permissions: | |
| contents: write |
.github/workflows/design-review.yml
Outdated
| npm init -y --quiet | ||
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet |
There was a problem hiding this comment.
The workflow runs npm init -y inside .github/scripts even though this PR adds a committed .github/scripts/package.json. This is unnecessary and can lead to confusing/unstable dependency installs; prefer using the checked-in package.json (and install from it) rather than re-initializing the project each run.
| npm init -y --quiet | |
| npm install @anthropic-ai/sdk@0.32.1 --save-exact --quiet | |
| npm install --quiet |
DESIGN_GUIDELINES.md
Outdated
| > **Allowed locations:** Hard-coded hex values are acceptable in token-definition and global-style layers where the palette is established: `tailwind.config.js`, `src/css/custom.css`, and other centralised theme/config files. | ||
| > | ||
| > **Migration note:** Existing hard-coded values in non-component files (e.g. `tailwind.config.js`) are pre-established palette definitions and should not be flagged. New component-level hard-coded hex values remain a Blocker. |
There was a problem hiding this comment.
This section allows hard-coded hex values in src/css/custom.css / tailwind.config.js, but later the document states “Never use hard-coded hex in CSS properties that affect visible elements — use CSS variables” (§6 Theme Rules). These rules conflict and will produce ambiguous enforcement. Consider explicitly carving out an exception for token-definition layers (where hex values define variables), and require variables everywhere else.
| > **Allowed locations:** Hard-coded hex values are acceptable in token-definition and global-style layers where the palette is established: `tailwind.config.js`, `src/css/custom.css`, and other centralised theme/config files. | |
| > | |
| > **Migration note:** Existing hard-coded values in non-component files (e.g. `tailwind.config.js`) are pre-established palette definitions and should not be flagged. New component-level hard-coded hex values remain a Blocker. | |
| > **Exception for token-definition layers only:** Hard-coded hex values are acceptable in central theme/config files such as `tailwind.config.js`, `src/css/custom.css`, and similar files **only when defining the palette or assigning CSS custom properties / theme tokens**. | |
| > | |
| > **Visible style rule:** Once a color token or CSS variable exists, use that variable/token everywhere else. Do **not** apply hard-coded hex values directly to visible CSS properties (for example `color`, `background`, `border`, `fill`, `stroke`, `box-shadow`) in components, pages, MDX wrappers, or general styling rules. | |
| > | |
| > **Migration note:** Existing hard-coded values in non-component files should be treated as valid only when they are part of token or palette definition. If a hard-coded hex in `src/css/custom.css` or another styling file directly affects a visible element instead of defining a token, replace it with the appropriate CSS variable. New direct-use hard-coded hex values remain a Blocker. |
DESIGN_GUIDELINES.md
Outdated
| ### Theme Rules | ||
|
|
||
| 1. **Every new CSS rule that sets color, background, or border must have a dark mode counterpart** inside `html[data-theme="dark"]` | ||
| 2. Never use hard-coded hex in CSS properties that affect visible elements — use CSS variables |
There was a problem hiding this comment.
Theme Rule #2 (“Never use hard-coded hex in CSS properties that affect visible elements — use CSS variables”) contradicts §2.1 which permits hex values in custom.css / tailwind.config.js as palette/token-definition files. Please reconcile these so the guideline is enforceable (e.g., allow hex only when defining tokens/variables, not when styling components).
| 2. Never use hard-coded hex in CSS properties that affect visible elements — use CSS variables | |
| 2. Hard-coded hex/RGB color values are allowed **only when defining design tokens/variables** (for example in `custom.css` theme variable blocks or `tailwind.config.js` theme tokens). When styling visible elements/components, always use CSS variables instead of literal color values. |
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
DESIGN_GUIDELINES.md
Outdated
| | D1 | Callouts use `:::type` Docusaurus syntax — not custom `<div>` elements | ❌ Blocker | | ||
| | D2 | Correct admonition type is used semantically (danger only for destructive, etc.) | ⚠️ Major | | ||
| | D3 | Code blocks have a language identifier (e.g., ` ```bash `) | ⚠️ Major | | ||
| | D4 | No inline `style` attribute on `<pre>`, `<code>`, or heading elements | ❌ Blocker | | ||
| | D5 | Tier badges use the defined `<span>` component — not custom styled `<div>` | ⚠️ Major | | ||
| | D6 | Tables have a header row (`<th>` elements) | ⚠️ Major | |
There was a problem hiding this comment.
This checklist rule is unconditional, but earlier the guidelines state GitHub-style admonitions (> [!NOTE], etc.) are tolerated in versioned_docs/. Since the agent is configured to review versioned_docs/**, leaving D1 as a hard “Blocker” will cause noisy/incorrect failures on legacy pages. Please clarify the scope (e.g., D1 applies to docs/ only) or add an explicit exception for versioned_docs/ to keep the document internally consistent.
| if (!process.env.GITHUB_TOKEN) { | ||
| console.error("ERROR: GITHUB_TOKEN environment variable is not set."); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| if (!process.env.GITHUB_REPOSITORY) { | ||
| console.error("ERROR: GITHUB_REPOSITORY environment variable is not set."); | ||
| process.exit(1); | ||
| } |
There was a problem hiding this comment.
These error logs don’t give a clear next step. Consider including actionable guidance (e.g., which workflow/env should set GITHUB_TOKEN / GITHUB_REPOSITORY, and how to fix it) so failures are easier to diagnose when the action runs.
Signed-off-by: amaan-bhati <amaanbhati49@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 8 out of 9 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
What has changed?
ill update the pr description once the implementation is completed
Please include a summary of the change.
This PR Resolves #(issue)
Type of change
Please delete options that are not relevant.
How Has This Been Tested?
Please run npm run build and npm run serve to check if the changes are working as expected. Please include screenshots of the output of both the commands. Add screenshots/gif of the changes if possible.
Checklist: