Files
Portfolio/AGENTS.md

12 KiB

Portfolio Project Development Rules

Code Style & Formatting

TypeScript

  • Tab indentation (not spaces), double quotes, semicolons required
  • Explicit function return types for all functions (except inline expressions)
  • Never use any type - always provide proper typing
  • Prefix interfaces with I (e.g., IProps), PascalCase for type aliases
  • Underscore prefix for unused variables (e.g., _unusedParam)
  • Avoid non-null assertions (!) - use proper null checks

React & JSX

  • Components return JSX.Element, functional components with hooks only
  • Self-closing tags for components without children: <Intro/>
  • No prop-types (using TypeScript)

Spacing & Formatting

  • Object curly spacing: { foo }, no array bracket spacing: [1, 2]
  • No trailing commas, arrow spacing: () => {}
  • Max 1 empty line between blocks, end files with newline, no trailing spaces

Imports

  • Use path alias @/* (configured in tsconfig)
  • Group: external deps first, then internal modules
  • Import from @/src/portfolio/... and @/src/styles/...

Project Structure

File Organization

  • Pages: /pages/*.tsx (pages router, not app router)
  • Components: /src/portfolio/sections/*.tsx
  • Styles: /src/styles/*.scss with helpers
  • Data: /src/portfolio/data/, Helpers: /src/portfolio/helpers/
  • Public: /public/ (PDFs, images, icons)

Component Structure

  • Section components in /src/portfolio/sections/, main page in /src/portfolio/MainPage.tsx
  • Each section has single responsibility

Styling & Libraries

SCSS

  • Import helpers: @import "helpers";, use variables: $accent_colour
  • BEM-like naming, !important only for library overrides (Splide)

Animations

  • AOS (scroll), Anime.js (complex), react-transition-group (transitions)
  • Respect prefers-reduced-motion

Tech Stack

  • Next.js 15 (pages router), React 18.2, TypeScript 5.1, SASS
  • @splidejs/react-splide, react-icons, Sharp
  • Dev server on port 4000: npm run dev

Development Workflow

Commands

  • npm run dev - Start dev server (port 4000)
  • npm run lintfix - Auto-fix linting issues
  • npm run lint - Check for issues
  • npm run build - Production build

Windsurf Commands Helper Script

The project includes windsurf-commands.sh for common development tasks:

./windsurf-commands.sh lint      # Run ESLint to check for code issues
./windsurf-commands.sh lintfix   # Run ESLint with auto-fix enabled
./windsurf-commands.sh help      # Show available commands

Usage in AGENTS.md:

  • When referencing linting in rules, can use either npm run lint or ./windsurf-commands.sh lint
  • Script provides consistent interface for development commands
  • Includes error handling and user-friendly output

Before Committing

  1. Run npm run lintfix and npm run lint
  2. Ensure TypeScript compiles
  3. Test changes in browser

File Naming

  • Components: PascalCase (MainPage.tsx)
  • Utilities: camelCase (helpers.ts)
  • Styles: kebab-case/camelCase (main.scss)

Common Patterns

// Component
const ComponentName = (): JSX.Element => {
	return <div>{/* content */}</div>;
};
export default ComponentName;

// Interface
interface IComponentProps {
	title: string;
	isActive: boolean;
}
// SCSS
@import "helpers";
.component { color: $accent_colour; }

Code Complexity Constraints

Strict Limits (ESLint Enforced)

  • Max line length: 120 characters (ignores URLs, strings, template literals)
  • Max file length: 300 lines (excluding blank lines and comments)
  • Max function length: 50 lines (excluding blank lines and comments)
  • Max cyclomatic complexity: 10 per function
  • Max nesting depth: 4 levels
  • Max parameters: 4 per function
  • Max nested callbacks: 3 levels
  • Max statements: 20 per function

Refactoring Strategies

When files exceed limits, use these approaches:

  1. Split by logical sections: Break large files into feature folders with main component, sub-components, helpers, types, and index.ts
  2. Extract helper functions: Move utility functions to separate helpers.ts files
  3. Extract types: Move interfaces/types to separate types.ts files
  4. Break down complex functions: Use sub-functions, early returns, extract conditionals, use lookup objects

Folder structure example:

/src/portfolio/sections/Experience/
  Experience.tsx, ExperienceCard.tsx, helpers.ts, types.ts, index.ts

Handling violations:

  1. Analyze what limit was exceeded
  2. Choose appropriate strategy
  3. Plan folder structure
  4. Execute incrementally (create files, move code, update imports, test)
  5. Verify with npm run lint

Line length fixes: Break strings, split chains, extract variables, reformat JSX Parameter count fixes: Use object parameters, configuration objects, or split function

QA and Testing

Pre-Testing Checklist

Before running any tests, verify the development server is running:

  1. Check if dev server is running using lsof:

    lsof -i :4000
    
    • If output shows a process, server is running
    • If no output, start the server with npm run dev
  2. Verify server accessibility:

    curl -I http://localhost:4000
    
    • Should return HTTP 200 OK
    • If connection refused, server needs to be started

Playwright MCP Testing Workflow

When testing changes or new features, follow this systematic approach:

Step 1: Environment Setup

  1. Ensure dev server is running on port 4000
  2. Install Playwright browsers if needed (use mcp0_browser_install if errors occur)
  3. Navigate to http://localhost:4000

Step 2: Visual Testing

Use Playwright MCP to verify visual elements:

  1. Take accessibility snapshot (mcp0_browser_snapshot):

    • Captures page structure and content
    • Better than screenshots for testing
    • Use this to verify all sections are present
  2. Check key sections are visible:

    • Intro section with name/title
    • Achievements section
    • Experience section with carousel
    • Projects section
    • Skills and Links section
    • Footer
  3. Verify responsive behavior:

    • Test at different viewport sizes using mcp0_browser_resize
    • Common breakpoints: 375px (mobile), 768px (tablet), 1920px (desktop)
    • Check that content adapts properly

Step 3: Functional Testing

Test interactive elements:

  1. Navigation and scrolling:

    • Verify smooth scroll behavior (if prefers-reduced-motion: no-preference)
    • Test anchor links if present
    • Check scroll-triggered animations (AOS)
  2. Carousel functionality (Splide):

    • Click next/previous arrows using mcp0_browser_click
    • Verify slides change correctly
    • Check pagination dots are clickable
    • Ensure carousel is responsive
  3. Interactive elements:

    • Test any buttons, links, or accordions
    • Verify hover states work
    • Check click handlers fire correctly
    • Test form inputs if present
  4. External links:

    • Verify PDF links open correctly (CV, research papers)
    • Check social media links
    • Ensure target="_blank" and rel="noopener noreferrer" where needed

Step 4: Accessibility Testing

  1. Contrast ratios:

    • Use mcp0_browser_evaluate to check computed styles
    • Verify text has sufficient contrast against backgrounds
    • Check accent color ($accent_colour) meets WCAG AA standards (4.5:1 for normal text)
  2. Keyboard navigation:

    • Use mcp0_browser_press_key to test Tab navigation
    • Verify focus indicators are visible
    • Check all interactive elements are keyboard accessible
    • Test Escape key for modals/overlays
  3. ARIA labels and semantic HTML:

    • Check snapshot for proper heading hierarchy (h1, h2, h3)
    • Verify buttons have accessible names
    • Check images have alt text
    • Ensure landmarks are properly labeled
  4. Screen reader compatibility:

    • Verify meaningful content order in accessibility snapshot
    • Check that hidden decorative elements are properly hidden
    • Ensure dynamic content updates are announced

Step 5: Performance Checks

  1. Console errors:

    • Use mcp0_browser_console_messages to check for errors
    • Verify no React warnings in development
    • Check for missing image errors
    • Look for failed network requests
  2. Network requests:

    • Use mcp0_browser_network_requests to inspect requests
    • Verify images are optimized (using Next.js Image)
    • Check for unnecessary requests
    • Ensure no 404s or failed requests
  3. Animation performance:

    • Verify AOS animations trigger smoothly
    • Check Anime.js animations don't cause jank
    • Test on reduced motion preference

Step 6: Cross-Section Integration

  1. Section transitions:

    • Scroll through all sections
    • Verify spacing between sections is consistent
    • Check that animations don't overlap or conflict
  2. Data consistency:

    • Verify project data displays correctly
    • Check experience timeline is accurate
    • Ensure skills list is complete and categorized
  3. Asset loading:

    • Verify all images load (profile, project screenshots)
    • Check PDFs are accessible
    • Ensure icons render correctly (react-icons)

Testing Checklist Template

When testing a new feature or change, use this checklist:

  • Dev server running on port 4000
  • Page loads without errors (check console)
  • All sections render correctly (accessibility snapshot)
  • Responsive at mobile (375px), tablet (768px), desktop (1920px)
  • Interactive elements work (carousels, buttons, links)
  • Keyboard navigation functional (Tab, Enter, Escape)
  • Contrast ratios meet WCAG AA standards
  • No console errors or warnings
  • Network requests successful (no 404s)
  • Animations smooth and respect reduced motion
  • External links open correctly
  • Images optimized and load properly

Common Test Scenarios

Testing a New Section Component

// 1. Check server is running
lsof -i :4000

// 2. Navigate and snapshot
mcp0_browser_navigate  http://localhost:4000
mcp0_browser_snapshot

// 3. Verify section appears
// Look for section in snapshot output

// 4. Test responsiveness
mcp0_browser_resize  375x667 (mobile)
mcp0_browser_snapshot
mcp0_browser_resize  1920x1080 (desktop)
mcp0_browser_snapshot

// 5. Check console
mcp0_browser_console_messages

Testing Accessibility

// 1. Check contrast
mcp0_browser_evaluate  
  function: () => {
    const el = document.querySelector('.your-element');
    const styles = window.getComputedStyle(el);
    return {
      color: styles.color,
      backgroundColor: styles.backgroundColor
    };
  }

// 2. Test keyboard navigation
mcp0_browser_press_key  Tab
mcp0_browser_snapshot  verify focus
mcp0_browser_press_key  Enter
mcp0_browser_snapshot  verify action

// 3. Check ARIA
mcp0_browser_snapshot  review for proper labels

When to Run Tests

  • Before committing: Run basic visual and console checks
  • After adding new section: Full section integration test
  • After styling changes: Visual + contrast + responsive tests
  • After adding interactivity: Functional + keyboard + accessibility tests
  • Before production build: Complete checklist + all scenarios

Debugging Failed Tests

  1. Visual issues: Take screenshot with mcp0_browser_take_screenshot for detailed inspection
  2. Functional issues: Use mcp0_browser_evaluate to inspect element state
  3. Network issues: Check mcp0_browser_network_requests for failed requests
  4. Console errors: Review mcp0_browser_console_messages for stack traces
  5. Timing issues: Use mcp0_browser_wait_for to wait for elements/animations

Notes

  • This is a portfolio website showcasing projects, experience, achievements, and skills
  • Runs on port 4000 (not default 3000)
  • Uses pages router (not app router)
  • Strict TypeScript and ESLint configuration for code quality
  • Tab-based indentation is non-negotiable (project standard)
  • Code complexity limits are strictly enforced - refactor proactively
  • Always test changes with Playwright MCP before committing
  • IMPORTANT: Always use Windsurf rules - they are allowed by default and enable much faster AI development progress