{"id":33301136,"url":"https://github.com/access-time/lenscore","last_synced_at":"2025-11-18T11:02:57.047Z","repository":{"id":323488344,"uuid":"1075833740","full_name":"Access-Time/LensCore","owner":"Access-Time","description":"🌐 LensCore is an open-source, API-first platform for web crawling and automated accessibility testing. Easily scan websites, detect WCAG issues with axe-core, and store reports, all in a fast, scalable, containerized environment","archived":false,"fork":false,"pushed_at":"2025-11-17T14:22:52.000Z","size":696,"stargazers_count":3,"open_issues_count":13,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-17T14:35:57.707Z","etag":null,"topics":["accessibility","axe-core","puppeteer","typescript","web-accessibility","web-crawler"],"latest_commit_sha":null,"homepage":"http://access-time.github.io/LensCore/en","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Access-Time.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-14T03:52:25.000Z","updated_at":"2025-11-17T08:55:35.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/Access-Time/LensCore","commit_stats":null,"previous_names":["access-time/lenscore"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Access-Time/LensCore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Access-Time%2FLensCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Access-Time%2FLensCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Access-Time%2FLensCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Access-Time%2FLensCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Access-Time","download_url":"https://codeload.github.com/Access-Time/LensCore/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Access-Time%2FLensCore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285051560,"owners_count":27106642,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-18T02:00:05.759Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["accessibility","axe-core","puppeteer","typescript","web-accessibility","web-crawler"],"created_at":"2025-11-18T11:00:34.875Z","updated_at":"2025-11-18T11:02:57.041Z","avatar_url":"https://github.com/Access-Time.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LensCore\n\n\u003cimg src=\"https://github.com/user-attachments/assets/a249eb4b-2ce5-4972-90ae-b3d2164e2b5a\" alt=\"AccessLine Logo\" width=\"170\" align=\"right\" /\u003e\n\n\u003cp\u003e\n\u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/License-MIT-yellow.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"CODE_OF_CONDUCT.md\"\u003e\u003cimg alt=\"Contributor Covenant\" src=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.docker.com/\"\u003e\u003cimg alt=\"Docker\" src=\"https://img.shields.io/badge/Docker-Ready-blue.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.typescriptlang.org/\"\u003e\u003cimg alt=\"TypeScript\" src=\"https://img.shields.io/badge/TypeScript-Ready-blue.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://nodejs.org/\"\u003e\u003cimg alt=\"Node.js\" src=\"https://img.shields.io/badge/Node.js-20+-green.svg\"\u003e\u003c/a\u003e\n\u003cbr/\u003e\n\u003ca href=\"https://pptr.dev/\"\u003e\u003cimg alt=\"Puppeteer\" src=\"https://img.shields.io/badge/Puppeteer-Web%20Automation-orange.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/dequelabs/axe-core\"\u003e\u003cimg alt=\"axe-core\" src=\"https://img.shields.io/badge/axe--core-Accessibility-red.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://expressjs.com/\"\u003e\u003cimg alt=\"Express\" src=\"https://img.shields.io/badge/Express-API%20Framework-lightgrey.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n**LensCore** is an open-source accessibility testing and web crawling platform built with a containerized, API-driven architecture. It provides comprehensive web accessibility analysis using axe-core integration and flexible storage options for screenshots and reports.\n\n## 🚀 Features\n\n- **🌐 Web Crawling**: Intelligent website crawling with configurable depth and rules\n- **♿ Accessibility Testing**: WCAG compliance testing powered by axe-core\n- **🤖 AI-Powered Analysis**: Plain language explanations and tech-stack specific remediation\n- **🧠 Intelligent Caching**: Smart caching system to minimize AI API costs and improve performance\n- **📸 Screenshot Capture**: Automatic screenshot capture for violations and pages\n- **💾 Flexible Storage**: Support for local, AWS S3, and Google Cloud Storage\n- **🔌 RESTful APIs**: Clean API endpoints for crawl, test, and combined operations\n- **🐳 Docker Ready**: Fully containerized with Docker Compose support\n- **⚡ High Performance**: Concurrent processing with configurable limits\n- **🛡️ Production Ready**: Built-in health checks, logging, and error handling\n\n## 📋 Table of Contents\n\n- [Quick Start](#-quick-start)\n- [Makefile Commands](#makefile-commands)\n- [Configuration](#️-configuration)\n- [API Documentation](#-api-documentation)\n- [AI Integration](#-ai-integration)\n- [Contributing](#-contributing)\n- [Code of Conduct](#code-of-conduct)\n- [License](#-license)\n\n## ⚡ Quick Start\n\n### Prerequisites\n\n- **Node.js** 20+ (for local development)\n- **Docker** \u0026 **Docker Compose** (for containerized deployment)\n- **Git** (for cloning the repository)\n\n### Using Docker (Recommended)\n\n1. **Clone the repository:**\n\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd LensCore\n   ```\n\n2. **Set up environment:**\n\n   ```bash\n   cp env.example .env\n   ```\n\n3. **Start the service (with Makefile):**\n\n   ```bash\n   make build-docker\n   ```\n\n4. **Verify installation:**\n\n   ```bash\n   curl http://localhost:3001/api/health\n   ```\n\n5. **Stop services:**\n   ```bash\n   make down\n   ```\n\n### Docker with Redis (Production)\n\nFor production deployments with Redis caching:\n\n1. **Set up environment:**\n\n   ```bash\n   cp env.example .env\n   # Edit .env and set CACHE_TYPE=redis\n   ```\n\n2. **Start with Redis:**\n\n   ```bash\n   docker-compose up -d --build\n   ```\n\n3. **Verify Redis connection:**\n\n   ```bash\n   curl http://localhost:3001/api/cache/stats\n   ```\n\n### Using Node.js\n\n1. **Install dependencies:**\n\n   ```bash\n   make install\n   ```\n\n2. **Set up environment:**\n\n   ```bash\n   cp env.example .env\n   ```\n\n3. **Start development server:**\n   ```bash\n   make dev\n   ```\n\n## Makefile Commands\n\nCommon tasks:\n\n```bash\nmake install      # Install dependencies\nmake dev          # Run development server\nmake build        # Build for production\nmake start        # Run production server\nmake test         # Run all tests\nmake lint         # Run ESLint\nmake format          # Format code with Prettier\nmake typecheck    # TypeScript type checking\n\nmake build-docker # Build Docker image\nmake up           # Start services with Docker Compose\nmake down         # Stop services with Docker Compose\nmake logs         # Tail Docker Compose logs\n\nmake env          # Print key env variables from .env\n```\n\n## ⚙️ Configuration\n\n### Environment Variables\n\nLensCore uses environment variables for configuration. Copy `env.example` to `.env` and customize as needed:\n\n#### Core Application Settings\n\n```env\nNODE_ENV=development\nPORT=3001\nLOG_LEVEL=info\n```\n\n#### Storage Configuration\n\n**Local Storage (Default):**\n\n```env\nSTORAGE_TYPE=local\nSTORAGE_PATH=./storage\n```\n\n**AWS S3:**\n\n```env\nSTORAGE_TYPE=s3\nAWS_ACCESS_KEY_ID=your_aws_access_key\nAWS_SECRET_ACCESS_KEY=your_aws_secret_key\nAWS_REGION=us-east-1\nAWS_S3_BUCKET=your-s3-bucket-name\n```\n\n**Google Cloud Storage:**\n\n```env\nSTORAGE_TYPE=gcs\nGCS_PROJECT_ID=your-gcs-project-id\nGCS_KEY_FILE_PATH=./path/to/service-account-key.json\nGCS_BUCKET_NAME=your-gcs-bucket-name\n```\n\n#### Crawling Configuration\n\n```env\nCRAWL_TIMEOUT=10000\nCRAWL_CONCURRENCY=5\nCRAWL_MAX_URLS=25\nCRAWL_WAIT_UNTIL=domcontentloaded\n```\n\n#### Accessibility Testing Configuration\n\n```env\nAXE_TIMEOUT=10000\nAXE_CONCURRENCY=5\n```\n\n#### AI Processing Configuration (Optional)\n\n```env\nOPENAI_API_KEY=your-openai-api-key\nOPENAI_MODEL=gpt-3.5-turbo\nOPENAI_MAX_TOKENS=1000\nOPENAI_TEMPERATURE=0.7\nOPENAI_TIMEOUT=30000\nOPENAI_RETRY_ATTEMPTS=3\nOPENAI_RETRY_DELAY=1000\n```\n\n#### Cache Configuration (Optional)\n\n```env\nCACHE_TYPE=memory          # memory, filesystem, redis\nCACHE_TTL=3600            # 1 hour in seconds\nCACHE_MAX_SIZE=1000       # For memory cache\nCACHE_PATH=./cache         # For filesystem cache\nREDIS_HOST=localhost       # Redis host\nREDIS_PORT=6379           # Redis port\nREDIS_PASSWORD=            # Redis password (optional)\nREDIS_DB=0                # Redis database\n```\n\n## 📚 API Documentation\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eBase URL \u0026 Response Format\u003c/strong\u003e\u003c/summary\u003e\n\n### Base URL\n\n```\nhttp://localhost:3001/api\n```\n\n### Response Format\n\nAll API responses follow a consistent JSON format with appropriate HTTP status codes.\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🏥 Health Check\u003c/strong\u003e\u003c/summary\u003e\n\nCheck the health status of all services.\n\n**Endpoint:** `GET /api/health`\n\n**Example:**\n\n```bash\ncurl http://localhost:3001/api/health\n```\n\n**Response:**\n\n```json\n{\n  \"status\": \"healthy\",\n  \"timestamp\": \"2024-01-01T00:00:00.000Z\",\n  \"services\": {\n    \"crawling\": \"up\",\n    \"accessibility\": \"up\",\n    \"storage\": \"up\"\n  }\n}\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🕷️ Crawl Website\u003c/strong\u003e\u003c/summary\u003e\n\nCrawl a website and discover all linked pages.\n\n**Endpoint:** `POST /api/crawl`\n\n**Request Body:**\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"max_depth\": 2,\n  \"maxUrls\": 10,\n  \"timeout\": 10000,\n  \"concurrency\": 3,\n  \"waitUntil\": \"domcontentloaded\",\n  \"rules\": {\n    \"include_subdomains\": true,\n    \"follow_external\": false,\n    \"exclude_paths\": [\"/admin\", \"/private\"],\n    \"include_paths\": [\"/public\", \"/docs\"],\n    \"respect_robots\": true\n  },\n  \"enableAI\": true,\n  \"projectContext\": {\n    \"framework\": \"React\",\n    \"cssFramework\": \"Tailwind CSS\",\n    \"language\": \"TypeScript\",\n    \"buildTool\": \"Vite\"\n  }\n}\n```\n\n**Parameters:**\n\n- `url` (required): Target website URL\n- `max_depth` (optional): Maximum crawling depth (1-5, default: 2)\n- `maxUrls` (optional): Maximum number of URLs to crawl (default: 25)\n- `timeout` (optional): Request timeout in milliseconds (default: 10000)\n- `concurrency` (optional): Number of concurrent requests (default: 5)\n- `waitUntil` (optional): Page load condition (default: \"domcontentloaded\")\n- `rules` (optional): Crawling rules configuration\n- `enableAI` (optional): Enable AI processing for accessibility issues (default: false)\n- `projectContext` (optional): Structured project context for more precise AI analysis\n\n**Crawling Rules:**\n\n- `include_subdomains` (optional): Include subdomains in crawling (default: false)\n- `follow_external` (optional): Follow external links (default: false)\n- `exclude_paths` (optional): Array of paths to exclude from crawling\n- `include_paths` (optional): Array of paths to include (if specified, only these paths will be crawled)\n- `respect_robots` (optional): Respect robots.txt (default: true)\n\n**Project Context Structure:**\n\n```json\n{\n  \"framework\": \"React\",\n  \"cssFramework\": \"Tailwind CSS\",\n  \"language\": \"TypeScript\",\n  \"buildTool\": \"Vite\",\n  \"additionalContext\": \"Custom context\"\n}\n```\n\n**Example:**\n\n```bash\ncurl -X POST http://localhost:3001/api/crawl \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"max_depth\": 2,\n    \"maxUrls\": 10,\n    \"timeout\": 10000,\n    \"concurrency\": 3,\n    \"rules\": {\n      \"include_subdomains\": true,\n      \"follow_external\": false,\n      \"exclude_paths\": [\"/admin\", \"/private\"]\n    },\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"framework\": \"React\",\n      \"cssFramework\": \"Tailwind CSS\",\n      \"language\": \"TypeScript\",\n      \"additionalContext\": \"Need to detail explanation\"\n    }\n  }'\n```\n\n**Response:**\n\n```json\n{\n  \"pages\": [\n    {\n      \"url\": \"https://example.com\",\n      \"title\": \"Example Domain\",\n      \"description\": \"This domain is for use in illustrative examples\",\n      \"statusCode\": 200,\n      \"timestamp\": \"2024-01-01T00:00:00.000Z\"\n    },\n    {\n      \"url\": \"https://example.com/about\",\n      \"title\": \"About Us\",\n      \"description\": \"Learn more about our company\",\n      \"statusCode\": 200,\n      \"timestamp\": \"2024-01-01T00:00:01.000Z\"\n    }\n  ],\n  \"totalPages\": 2,\n  \"crawlTime\": 2500,\n  \"metadata\": {\n    \"crawledAt\": \"2024-01-01T00:00:02.000Z\",\n    \"maxDepth\": 2,\n    \"rules\": {\n      \"include_subdomains\": true,\n      \"follow_external\": false,\n      \"exclude_paths\": [\"/admin\", \"/private\"]\n    },\n    \"totalPages\": 2,\n    \"crawlTime\": 2500,\n    \"aiEnabled\": true,\n    \"cacheHits\": 0,\n    \"cacheMisses\": 0,\n    \"processingTime\": 150\n  }\n}\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e♿ Test Accessibility\u003c/strong\u003e\u003c/summary\u003e\n\nRun accessibility tests on a single page using axe-core.\n\n**Endpoint:** `POST /api/test`\n\n**Request Body:**\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"includeScreenshot\": true,\n  \"timeout\": 10000,\n  \"rules\": [\"color-contrast\", \"image-alt\"],\n  \"tags\": [\"wcag2aa\", \"wcag143\"],\n  \"enableAI\": true,\n  \"projectContext\": {\n    \"framework\": \"Vue.js\",\n    \"cssFramework\": \"Bootstrap\",\n    \"language\": \"JavaScript\"\n  }\n}\n```\n\n**Parameters:**\n\n- `url` (required): Target page URL\n- `includeScreenshot` (optional): Capture screenshot (default: false)\n- `timeout` (optional): Test timeout in milliseconds (default: 10000)\n- `rules` (optional): Specific axe-core rules to test\n- `tags` (optional): WCAG tags to include in testing\n- `enableAI` (optional): Enable AI processing for accessibility issues (default: false)\n- `projectContext` (optional): Structured project context for more precise AI analysis\n\n**Project Context Structure:**\n\n```json\n{\n  \"framework\": \"React\",\n  \"cssFramework\": \"Tailwind CSS\",\n  \"language\": \"TypeScript\",\n  \"buildTool\": \"Vite\",\n  \"additionalContext\": \"Custom context\"\n}\n```\n\n**Example:**\n\n```bash\ncurl -X POST http://localhost:3001/api/test \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"includeScreenshot\": true,\n    \"timeout\": 10000,\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"framework\": \"Next.js\",\n      \"cssFramework\": \"Tailwind CSS\",\n      \"language\": \"TypeScript\"\n    }\n  }'\n```\n\n**Response:**\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"score\": 85,\n  \"violations\": [\n    {\n      \"id\": \"color-contrast\",\n      \"impact\": \"serious\",\n      \"description\": \"Ensures the contrast between foreground and background colors meets WCAG 2 AA contrast ratio thresholds\",\n      \"help\": \"Elements must have sufficient color contrast\",\n      \"helpUrl\": \"https://dequeuniversity.com/rules/axe/4.8/color-contrast\",\n      \"tags\": [\"cat.color\", \"wcag2aa\", \"wcag143\"],\n      \"nodes\": [\n        {\n          \"target\": [\"h1\"],\n          \"html\": \"\u003ch1\u003eExample Domain\u003c/h1\u003e\",\n          \"failureSummary\": \"Fix any of the following:\\n  Element has insufficient color contrast of 2.52 (foreground color: #000000, background color: #ffffff, font size: 32px, font weight: normal). Expected contrast ratio of at least 3:1\"\n        }\n      ],\n      \"aiExplanation\": \"This accessibility issue occurs when text doesn't have enough contrast against its background...\",\n      \"aiRemediation\": \"To fix this issue:\\n1. Increase color contrast ratio...\\n2. Use CSS: color: #000; background: #fff;\",\n      \"userStory\": \"Users with screen readers have difficulty navigating because there is no clear main landmark. Users who use keyboard navigation cannot jump to the main content quickly. Users with cognitive disabilities may be confused by unclear page structure.\"\n    }\n  ],\n  \"passes\": [],\n  \"incomplete\": [],\n  \"inapplicable\": [],\n  \"screenshot\": \"https://storage.example.com/screenshots/uuid.png\",\n  \"timestamp\": \"2024-01-01T00:00:00.000Z\",\n  \"aiEnabled\": true,\n  \"aiError\": null\n}\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🔄 Test Multiple Pages\u003c/strong\u003e\u003c/summary\u003e\n\nRun accessibility tests on multiple pages simultaneously.\n\n**Endpoint:** `POST /api/test-multiple`\n\n**Request Body:**\n\n```json\n[\n  {\n    \"url\": \"https://example.com\",\n    \"includeScreenshot\": true,\n    \"timeout\": 10000\n  },\n  {\n    \"url\": \"https://example.com/about\",\n    \"includeScreenshot\": true,\n    \"timeout\": 10000\n  }\n]\n```\n\n**Example:**\n\n```bash\ncurl -X POST http://localhost:3001/api/test-multiple \\\n  -H \"Content-Type: application/json\" \\\n  -d '[\n    {\n      \"url\": \"https://example.com\",\n      \"includeScreenshot\": true\n    },\n    {\n      \"url\": \"https://example.com/about\",\n      \"includeScreenshot\": true\n    }\n  ]'\n```\n\n**Response:**\n\n```json\n{\n  \"results\": [\n    {\n      \"url\": \"https://example.com\",\n      \"score\": 85,\n      \"violations\": [...],\n      \"passes\": [],\n      \"incomplete\": [],\n      \"inapplicable\": [],\n      \"screenshot\": \"https://storage.example.com/screenshots/uuid1.png\",\n      \"timestamp\": \"2024-01-01T00:00:00.000Z\"\n    },\n    {\n      \"url\": \"https://example.com/about\",\n      \"score\": 92,\n      \"violations\": [...],\n      \"passes\": [],\n      \"incomplete\": [],\n      \"inapplicable\": [],\n      \"screenshot\": \"https://storage.example.com/screenshots/uuid2.png\",\n      \"timestamp\": \"2024-01-01T00:00:00.000Z\"\n    }\n  ],\n  \"totalPages\": 2,\n  \"testTime\": 3000\n}\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🚀 Combined Crawl and Test\u003c/strong\u003e\u003c/summary\u003e\n\nCrawl a website and run accessibility tests on all discovered pages.\n\n**Endpoint:** `POST /api/combined`\n\n**Request Body:**\n\n```json\n{\n  \"url\": \"https://example.com\",\n  \"crawlOptions\": {\n    \"maxUrls\": 5,\n    \"concurrency\": 2,\n    \"timeout\": 10000\n  },\n  \"testOptions\": {\n    \"includeScreenshot\": true,\n    \"timeout\": 15000,\n    \"rules\": [\"color-contrast\"]\n  },\n  \"enableAI\": true,\n  \"projectContext\": {\n    \"framework\": \"Angular\",\n    \"cssFramework\": \"Material UI\",\n    \"language\": \"TypeScript\"\n  }\n}\n```\n\n**Parameters:**\n\n- `url` (required): Target website URL\n- `crawlOptions` (optional): Crawling configuration (see crawl API)\n- `testOptions` (optional): Testing configuration (see test API)\n- `enableAI` (optional): Enable AI processing for accessibility issues (default: false)\n- `projectContext` (optional): Structured project context for more precise AI analysis\n\n**Project Context Structure:**\n\n```json\n{\n  \"framework\": \"React\",\n  \"cssFramework\": \"Tailwind CSS\",\n  \"language\": \"TypeScript\",\n  \"buildTool\": \"Vite\",\n  \"additionalContext\": \"Custom context\"\n}\n```\n\n**Example:**\n\n```bash\ncurl -X POST http://localhost:3001/api/combined \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"crawlOptions\": {\n      \"maxUrls\": 5,\n      \"concurrency\": 2\n    },\n    \"testOptions\": {\n      \"includeScreenshot\": true,\n      \"timeout\": 15000\n    },\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"framework\": \"React\",\n      \"cssFramework\": \"Tailwind CSS\",\n      \"language\": \"TypeScript\"\n    }\n  }'\n```\n\n**Response:**\n\n```json\n{\n  \"crawl\": {\n    \"pages\": [\n      {\n        \"url\": \"https://example.com\",\n        \"title\": \"Example Domain\",\n        \"description\": \"This domain is for use in illustrative examples\",\n        \"statusCode\": 200,\n        \"timestamp\": \"2024-01-01T00:00:00.000Z\"\n      }\n    ],\n    \"totalPages\": 1,\n    \"crawlTime\": 3000\n  },\n  \"accessibility\": {\n    \"results\": [\n      {\n        \"url\": \"https://example.com\",\n        \"score\": 85,\n        \"violations\": [\n          {\n            \"id\": \"color-contrast\",\n            \"impact\": \"serious\",\n            \"description\": \"Elements must have sufficient color contrast\",\n            \"help\": \"Ensure all text elements have sufficient color contrast\",\n            \"helpUrl\": \"https://dequeuniversity.com/rules/axe/4.8/color-contrast\",\n            \"nodes\": [...],\n            \"aiExplanation\": \"This accessibility issue occurs when text doesn't have enough contrast...\",\n            \"aiRemediation\": \"To fix this issue:\\n1. Increase color contrast ratio...\\n2. Use CSS: color: #000; background: #fff;\"\n          }\n        ],\n        \"passes\": [],\n        \"incomplete\": [],\n        \"inapplicable\": [],\n        \"screenshot\": \"https://storage.example.com/screenshots/uuid.png\",\n        \"timestamp\": \"2024-01-01T00:00:00.000Z\",\n        \"aiEnabled\": true,\n        \"aiError\": null\n      }\n    ],\n    \"totalPages\": 1,\n    \"testTime\": 15000\n  },\n  \"totalTime\": 18000\n}\n```\n\n\u003c/details\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🗄️ Cache Management\u003c/strong\u003e\u003c/summary\u003e\n\nManage the intelligent caching system for AI responses.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eGet Cache Statistics\u003c/strong\u003e\u003c/summary\u003e\n\n**Endpoint:** `GET /api/cache/stats`\n\n**Example:**\n\n```bash\ncurl http://localhost:3001/api/cache/stats\n```\n\n**Response:**\n\n```json\n{\n  \"status\": \"success\",\n  \"data\": {\n    \"hits\": 15,\n    \"misses\": 8,\n    \"size\": 12,\n    \"hitRate\": 0.65\n  }\n}\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eClear Cache\u003c/strong\u003e\u003c/summary\u003e\n\n**Endpoint:** `DELETE /api/cache/clear`\n\n**Example:**\n\n```bash\ncurl -X DELETE http://localhost:3001/api/cache/clear\n```\n\n**Response:**\n\n```json\n{\n  \"status\": \"success\",\n  \"message\": \"Cache cleared successfully\"\n}\n```\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n---\n\n## 🤖 AI Integration\n\nLensCore includes optional AI-powered analysis for accessibility issues, providing plain language explanations and tech-stack specific remediation steps.\n\n### Features\n\n- **Plain Language Explanations**: Convert technical accessibility issues into easy-to-understand explanations\n- **Tech-Stack Specific Remediation**: Get specific, actionable steps tailored to your technology stack\n- **Dynamic Prompt Engineering**: Intelligent prompt generation based on project context\n- **Structured Response Parsing**: Consistent JSON response format with fallback handling\n- **Optional Processing**: AI processing is opt-in and doesn't affect existing functionality\n- **Cost Effective**: Only processes AI when explicitly requested\n\n### Usage\n\n**Project Context (Recommended):**\n\n```json\n{\n  \"enableAI\": true,\n  \"projectContext\": {\n    \"framework\": \"React\",\n    \"cssFramework\": \"Tailwind CSS\",\n    \"language\": \"TypeScript\",\n    \"buildTool\": \"Vite\"\n  }\n}\n```\n\n**Backward Compatibility (Tech Stack String):**\n\n```json\n{\n  \"enableAI\": true,\n  \"projectContext\": {\n    \"additionalContext\": \"React, TypeScript, Tailwind CSS\"\n  }\n}\n```\n\n### Response Fields\n\nWhen AI is enabled, responses include additional fields:\n\n- `aiExplanation`: Plain language explanation of the accessibility issue\n- `aiRemediation`: Specific steps to fix the issue with code examples\n- `userStory`: Human-readable impact explanation for the accessibility issue\n- `aiEnabled`: Boolean indicating if AI processing was successful\n- `aiError`: Error message if AI processing failed\n\n### Configuration\n\nSet your OpenAI API key in environment variables:\n\n```env\nOPENAI_API_KEY=your-openai-api-key\n```\n\n### AI Prompt Engineering\n\nLensCore uses advanced prompt engineering to generate context-aware responses:\n\n**Automatic Tech Stack Detection:**\n\n- Framework: React, Vue.js, Angular, Svelte, Next.js, Nuxt.js\n- CSS Framework: Tailwind CSS, Bootstrap, Material UI, Chakra UI\n- Language: TypeScript, JavaScript\n- Build Tools: Webpack, Vite, Rollup, Parcel\n\n**Response Format:**\n\n```json\n{\n  \"rule_id\": \"color-contrast\",\n  \"plain_explanation\": \"This text has insufficient contrast for users with visual impairments.\",\n  \"remediation\": \"Use Tailwind CSS classes like text-gray-800 or text-gray-900 for better contrast.\"\n}\n```\n\n**Fallback Handling:**\n\n- Automatic fallback responses if AI fails\n- Graceful degradation without breaking the API\n- Consistent response structure\n\n### Examples\n\n**Test with AI (Project Context):**\n\n```bash\ncurl -X POST http://localhost:3001/api/test \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"framework\": \"Vue.js\",\n      \"cssFramework\": \"Bootstrap\",\n      \"language\": \"JavaScript\"\n    }\n  }'\n```\n\n**Test with AI (Backward Compatibility):**\n\n```bash\ncurl -X POST http://localhost:3001/api/test \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"additionalContext\": \"Vue.js, JavaScript, Bootstrap\"\n    }\n  }'\n```\n\n**Combined with AI:**\n\n```bash\ncurl -X POST http://localhost:3001/api/combined \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"url\": \"https://example.com\",\n    \"enableAI\": true,\n    \"projectContext\": {\n      \"framework\": \"Next.js\",\n      \"cssFramework\": \"Tailwind CSS\",\n      \"language\": \"TypeScript\"\n    }\n  }'\n```\n\n---\n\n## 🤝 Contributing\n\nWe welcome contributions! Whether you're fixing bugs, adding features, or improving documentation, your help makes LensCore better.\n\nSee our [Contributing Guide](CONTRIBUTING.md) for details on how to get started.\n\n---\n\n## Code of Conduct\n\nThis project adheres to the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md) to ensure a welcoming and inclusive environment for all contributors. By participating in this project, you are expected to uphold this code. Please report any violations to the project maintainers.\n\n---\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- [axe-core](https://github.com/dequelabs/axe-core) for accessibility testing\n- [Puppeteer](https://github.com/puppeteer/puppeteer) for web automation\n- [Express.js](https://expressjs.com/) for the web framework\n- [OpenAI](https://openai.com/) for AI-powered accessibility analysis\n- [Docker](https://www.docker.com/) for containerization\n\n---\n\n**Made with ❤️ by the AccessTime team**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccess-time%2Flenscore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccess-time%2Flenscore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccess-time%2Flenscore/lists"}