Enforce strict co-location pattern in website app#46
Conversation
- Extract page sections into dedicated components (HeroSection, ClientLogosSection, ScaleFeaturesSection, FeaturesSection) - Nest sub-components under parent's components/ directory when only used once - Move shared layout components (Header, Footer, WaitlistModal) to components/layout/ - Co-locate constants, config, hooks, and shaders with their components - Reduce main page.tsx from 419 lines to ~30 lines of orchestration - Add comprehensive Project Structure documentation to AGENTS.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Move Header, Footer, WaitlistModal to app/components/ (used only in page.tsx) - Extract HeroCanvas multi-component file: - calculateGlareProperties → helpers.ts - LitBackground → components/LitBackground/ - Delete unused ScaleFeaturesSection component - Update all imports to use relative paths - Add project-structure-validator agent for ongoing compliance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughAdds project-structure-validator docs and tooling, updates AGENTS.md with project-structure guidance, introduces UI components (HeroSection, HeroCanvas and shaders, ClientLogosSection, FeaturesSection), consolidates barrel exports, refactors page composition, removes a motion component and index exports, and adds a script to build a component import graph. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant P as page.tsx
participant H as Header
participant Hero as HeroSection
participant C as HeroCanvas
participant L as ClientLogosSection
participant F as FeaturesSection
participant M as WaitlistModal
participant Ft as Footer
U->>P: request page
P->>H: render Header
P->>Hero: render HeroSection
Hero->>C: initialize three.js Canvas
C->>C: load config & shaders\ncompute glare via helpers
P->>L: render ClientLogosSection (marquee)
P->>F: render FeaturesSection (pass onOpenWaitlist)
U->>F: click "Join waitlist"
F->>P: onOpenWaitlist()
P->>M: open WaitlistModal
U->>M: interact / close
P->>Ft: render Footer
sequenceDiagram
autonumber
participant Script as build-component-graph.sh
participant FS as File system
participant Parser as grep / sed / awk
participant Out as .component-graph.json
Script->>FS: find TS/TSX files (exclude tests/stories/node_modules)
Script->>Parser: extract import statements & component names
Parser->>Script: aggregate import counts and importers
Script->>Out: write JSON graph (.component-graph.json)
Script->>FS: log output path
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Focus review on:
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
AGENTS.md (1)
77-114: Add languages to fenced code blocks.Markdownlint (MD040) is flagging these tree/layout snippets because the fences lack a language hint. Adding something like ```text (or another appropriate language) will clear the warnings and keep automated docs checks happy.
WEB_APP_RESTRUCTURE_PLAN.md (1)
22-41: Annotate fenced code blocks with a language.Same markdownlint MD040 warning here—the large structure block is missing a language identifier. Please add ```text (or whichever fits best) so the documentation lint stays green.
apps/website/src/app/components/HeroSection/components/HeroCanvas/shaders/fragment.ts (1)
1-35: Remove unused uniform or wire it into the shader
uMetalnessis declared, set from config, and uploaded every frame, but it never factors into the lighting math. Please either put it to use (e.g., blend it into the specular term) or drop the uniform so the shader stays lean and easier to reason about.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
.claude/agents/project-structure-validator.md(1 hunks)AGENTS.md(2 hunks)WEB_APP_RESTRUCTURE_PLAN.md(1 hunks)apps/website/src/app/components/ClientLogosSection/ClientLogosSection.tsx(1 hunks)apps/website/src/app/components/ClientLogosSection/constants.ts(1 hunks)apps/website/src/app/components/ClientLogosSection/index.ts(1 hunks)apps/website/src/app/components/FeaturesSection/FeaturesSection.tsx(1 hunks)apps/website/src/app/components/FeaturesSection/index.ts(1 hunks)apps/website/src/app/components/Footer/index.ts(1 hunks)apps/website/src/app/components/Header/Header.tsx(1 hunks)apps/website/src/app/components/Header/index.ts(1 hunks)apps/website/src/app/components/HeroSection/HeroSection.tsx(1 hunks)apps/website/src/app/components/HeroSection/components/FadeUp/index.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/HeroCanvas.tsx(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/components/LitBackground/LitBackground.tsx(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/components/LitBackground/index.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/config.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/helpers.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/shaders/fragment.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroCanvas/shaders/vertex.ts(1 hunks)apps/website/src/app/components/HeroSection/components/HeroParallax/index.ts(1 hunks)apps/website/src/app/components/HeroSection/index.ts(1 hunks)apps/website/src/app/components/WaitlistModal/index.ts(1 hunks)apps/website/src/app/page.tsx(1 hunks)apps/website/src/components/motion/TiltCard.tsx(0 hunks)apps/website/src/components/motion/index.ts(0 hunks)
💤 Files with no reviewable changes (2)
- apps/website/src/components/motion/index.ts
- apps/website/src/components/motion/TiltCard.tsx
🧰 Additional context used
🧬 Code graph analysis (6)
apps/website/src/app/components/HeroSection/HeroSection.tsx (3)
apps/website/src/app/components/HeroSection/components/HeroParallax/HeroParallax.tsx (1)
HeroParallax(20-63)apps/website/src/app/components/HeroSection/components/HeroCanvas/HeroCanvas.tsx (1)
HeroCanvas(11-39)apps/website/src/app/components/HeroSection/components/FadeUp/FadeUp.tsx (1)
FadeUp(24-46)
apps/website/src/app/components/HeroSection/components/HeroCanvas/helpers.ts (1)
apps/website/src/app/components/HeroSection/components/HeroCanvas/config.ts (1)
TEXT_CONFIG(33-49)
apps/website/src/app/components/ClientLogosSection/ClientLogosSection.tsx (1)
apps/website/src/app/components/ClientLogosSection/constants.ts (1)
CLIENT_LOGOS(1-11)
apps/website/src/app/components/FeaturesSection/FeaturesSection.tsx (1)
apps/website/src/app/components/FeaturesSection/index.ts (1)
FeaturesSection(1-1)
apps/website/src/app/components/HeroSection/components/HeroCanvas/HeroCanvas.tsx (1)
apps/website/src/app/components/HeroSection/components/HeroCanvas/components/LitBackground/LitBackground.tsx (1)
LitBackground(19-258)
apps/website/src/app/components/HeroSection/components/HeroCanvas/components/LitBackground/LitBackground.tsx (1)
apps/website/src/app/components/HeroSection/components/HeroCanvas/components/LitBackground/index.ts (1)
LitBackground(1-1)
🪛 markdownlint-cli2 (0.18.1)
AGENTS.md
76-76: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
WEB_APP_RESTRUCTURE_PLAN.md
21-21: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
52-52: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
226-226: Emphasis used instead of a heading
(MD036, no-emphasis-as-heading)
228-228: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
374-374: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (8)
apps/website/src/app/components/Header/Header.tsx (1)
5-5: LGTM! Import path correctly updated for new structure.The import path change from
"./WaitlistModal"to"../WaitlistModal"correctly reflects the restructured co-location whereWaitlistModalis now a sibling directory undercomponents/rather than nested withinHeader/.apps/website/src/app/components/ClientLogosSection/index.ts (1)
1-1: LGTM! Clean barrel export.Standard barrel export pattern that enables cleaner imports and aligns with the co-location structure.
apps/website/src/app/components/FeaturesSection/index.ts (1)
1-1: LGTM! Consistent barrel export.Follows the same clean pattern as other component exports in this refactoring.
apps/website/src/app/components/HeroSection/components/HeroParallax/index.ts (1)
1-1: LGTM! Multi-export barrel.Correctly exports both the component and its associated hook, maintaining a clean public API.
apps/website/src/app/components/HeroSection/components/FadeUp/index.ts (1)
1-1: LGTM! Standard barrel export.Clean component re-export following the established pattern.
apps/website/src/app/components/HeroSection/index.ts (1)
1-1: LGTM! Top-level component export.Standard barrel export for the HeroSection component, consistent with other top-level sections.
apps/website/src/app/components/Header/index.ts (1)
1-1: LGTM! Header component export.Enables clean imports of the Header component via the directory path.
apps/website/src/app/components/Footer/index.ts (1)
1-1: LGTM! Footer component export.Final component barrel export completing the consistent co-location pattern across all top-level sections.
| className="flex gap-12 sm:gap-16 md:gap-24" | ||
| animate={{ | ||
| x: [0, -1000], | ||
| }} | ||
| transition={{ | ||
| x: { | ||
| repeat: Number.POSITIVE_INFINITY, | ||
| repeatType: "loop", | ||
| duration: 20, | ||
| ease: "linear", | ||
| }, |
There was a problem hiding this comment.
Fix marquee offset to avoid gaps
Hard-coding x: [0, -1000] makes the marquee drift out of sync with the actual logo width. On wider viewports the strip resets before the next copy lines up, producing a backward jump; on narrower viewports it keeps sliding past the content and leaves blank space before looping. Drive the animation with a relative offset so the second copy is always aligned when the loop restarts.
- animate={{
- x: [0, -1000],
- }}
+ animate={{
+ x: ["0%", "-33.333333%"],
+ }}
transition={{
x: {
repeat: Number.POSITIVE_INFINITY,
repeatType: "loop",
duration: 20,
ease: "linear",📝 Committable suggestion
‼️ 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.
| className="flex gap-12 sm:gap-16 md:gap-24" | |
| animate={{ | |
| x: [0, -1000], | |
| }} | |
| transition={{ | |
| x: { | |
| repeat: Number.POSITIVE_INFINITY, | |
| repeatType: "loop", | |
| duration: 20, | |
| ease: "linear", | |
| }, | |
| className="flex gap-12 sm:gap-16 md:gap-24" | |
| animate={{ | |
| x: ["0%", "-33.333333%"], | |
| }} | |
| transition={{ | |
| x: { | |
| repeat: Number.POSITIVE_INFINITY, | |
| repeatType: "loop", | |
| duration: 20, | |
| ease: "linear", | |
| }, |
- Add component graph builder script for fast dependency analysis - Update agent to always build graph first (avoids 15-20+ grep operations) - Add test coverage checking requirement (rule #5) - Define concise output format with performance tracking - Add self-improvement requirement for iterative agent refinement - Co-locate all agent resources in .claude/agents/project-structure-validator/ - Add .gitignore for generated graph files Performance improvements: - Reduced tool calls from 30+ to ~10 - Pre-computed import counts eliminate slow grep operations - Test coverage check integrated into workflow Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Test co-location is optional, not mandatory. Removed: - Bullet #5 from AGENTS.md structure rules - Test coverage checks from agent validation steps - Test coverage metrics from agent output format 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
AGENTS.md (2)
98-103: Align test file examples with Rule 5 requirement.Rule 5 (line 124–125) mandates co-located
.test.tsxfiles for all components, but the examples forSidebarNavandSidebarFooteromit them. For consistency and clarity, either:
- Add
.test.tsxfiles to these examples, or- Document when test files are optional
Compare with the
HeroCanvasexample (line 111), which correctly shows the test file.Apply this diff to include test files:
│ ├── SidebarNav/ │ │ ├── SidebarNav.tsx +│ │ ├── SidebarNav.test.tsx │ │ └── index.ts │ └── SidebarFooter/ │ ├── SidebarFooter.tsx +│ ├── SidebarFooter.test.tsx │ └── index.ts
120-122: Clarify "highest shared parent" guidance in Rule 2.The co-location rule states "If used 2+ times, promote to highest shared parent's
components/," but it's unclear how to handle components used across unrelated branches (e.g., bothdashboard/andsettings/). When no natural parent exists, should they go directly toapp/components/?Consider adding an example or explicit guidance to reduce ambiguity.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
AGENTS.md(2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
AGENTS.md
76-76: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (1)
AGENTS.md (1)
72-125: Excellent documentation for Project Structure enforcement.The new section provides prescriptive, well-structured guidance with clear examples and actionable rules. This aligns well with the PR's goal to enforce co-location and modularization. The examples effectively demonstrate nesting depth, test co-location, and the "last resort" top-level
components/pattern.
|
|
||
| All projects in this repo should be structured like this: | ||
|
|
||
| ``` |
There was a problem hiding this comment.
Add language identifier to fenced code block.
The code block is missing a language specifier, which violates MD040 and impacts syntax highlighting. Update the opening fence to include text or bash.
-```
+```text
app/
├── page.tsx🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
76-76: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In AGENTS.md around line 76, the fenced code block opening fence is missing a
language identifier (violates MD040); update the opening fence to include a
language such as text or bash (e.g., change ``` to ```text) so the block becomes
a proper fenced code block with syntax highlighting.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.claude/agents/project-structure-validator.md(1 hunks)AGENTS.md(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .claude/agents/project-structure-validator.md
🧰 Additional context used
🪛 markdownlint-cli2 (0.18.1)
AGENTS.md
76-76: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (2)
AGENTS.md (2)
72-123: Well-structured Project Structure guidance with clear co-location rules.The new section provides comprehensive, prescriptive guidance on folder layout and component co-location. The rules are clear:
- One component per file
- Co-locate dependencies (hooks, utils, constants, tests)
- Promote to shared parent's
components/only when used 2+ times- Use
components/at app root as a last resortExamples are concrete and illustrative. The guidance aligns well with the PR objectives of enforcing strict co-location patterns. The addition of test, story, and config co-location alongside components demonstrates practical understanding.
14-15: Improved documentation clarity with new agent rules and packages/ui guidance.
- Lines 14–15: Clear, inline instruction for adding shadcn components improves discoverability.
- Lines 68–70: New rules (type safety, avoid running dev servers, search narrowly) are sensible additions that support code quality and automation constraints.
Also applies to: 68-70
| ``` | ||
| app/ | ||
| ├── page.tsx |
There was a problem hiding this comment.
Fix missing language identifier in fenced code block (MD040).
The opening fence at line 76 is missing a language specifier, which violates MD040. This was previously flagged and remains unresolved. Update the opening fence to include text:
-```
+```text
app/
├── page.tsx🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
76-76: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
In AGENTS.md around lines 76 to 78, the fenced code block opening fence is
missing a language identifier (MD040); update the opening fence to include the
language specifier "text" so the block starts with ```text and the listed tree
lines remain unchanged, then save the file.
* Restructure website app with strict co-location pattern - Extract page sections into dedicated components (HeroSection, ClientLogosSection, ScaleFeaturesSection, FeaturesSection) - Nest sub-components under parent's components/ directory when only used once - Move shared layout components (Header, Footer, WaitlistModal) to components/layout/ - Co-locate constants, config, hooks, and shaders with their components - Reduce main page.tsx from 419 lines to ~30 lines of orchestration - Add comprehensive Project Structure documentation to AGENTS.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Enforce strict co-location pattern in website app - Move Header, Footer, WaitlistModal to app/components/ (used only in page.tsx) - Extract HeroCanvas multi-component file: - calculateGlareProperties → helpers.ts - LitBackground → components/LitBackground/ - Delete unused ScaleFeaturesSection component - Update all imports to use relative paths - Add project-structure-validator agent for ongoing compliance 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Improve project-structure-validator agent performance and output - Add component graph builder script for fast dependency analysis - Update agent to always build graph first (avoids 15-20+ grep operations) - Add test coverage checking requirement (rule #5) - Define concise output format with performance tracking - Add self-improvement requirement for iterative agent refinement - Co-locate all agent resources in .claude/agents/project-structure-validator/ - Add .gitignore for generated graph files Performance improvements: - Reduced tool calls from 30+ to ~10 - Pre-computed import counts eliminate slow grep operations - Test coverage check integrated into workflow Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove Structure Rules heading from AGENTS.md 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * Remove test coverage requirement from structure rules Test co-location is optional, not mandatory. Removed: - Bullet #5 from AGENTS.md structure rules - Test coverage checks from agent validation steps - Test coverage metrics from agent output format 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
Summary
Refactored website app to strictly follow the co-location pattern defined in AGENTS.md. Moved components to correct nesting levels based on usage, extracted multi-component files, and removed dead code.
Changes
Testing
All type checks pass. Components are correctly co-located and follow architectural patterns.
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Refactoring
Removals
Documentation