diff --git a/.github/badges.yml b/.github/badges.yml index 1fe298b..6131369 100644 --- a/.github/badges.yml +++ b/.github/badges.yml @@ -1,10 +1,18 @@ -badges: - - name: Build Status - image: https://img.shields.io/github/actions/workflow/status/{owner}/{repo}/ci.yml?label=Build&style=flat-square - url: https://github.com/{owner}/{repo}/actions/workflows/ci.yml - - name: License - image: https://img.shields.io/badge/License-CC%20BY--NC%204.0-blue.svg?style=flat-square - url: LICENSE - - name: GitHub Stars - image: https://img.shields.io/github/stars/{owner}/{repo}?style=flat-square - url: https://github.com/{owner}/{repo} +- name: 'License' + shield: 'https://img.shields.io/badge/license-CC%20BY--NC%204.0-blue.svg' + url: 'https://creativecommons.org/licenses/by-nc/4.0/' +- name: 'Vite' + shield: 'https://img.shields.io/badge/vite-^7.2.4-blue.svg' + url: 'https://vitejs.dev/' +- name: 'TypeScript' + shield: 'https://img.shields.io/badge/typescript-^6.0.0--beta-blue.svg' + url: 'https://www.typescriptlang.org/' +- name: 'Tailwind CSS' + shield: 'https://img.shields.io/badge/tailwind%20css-^4.1.18-blue.svg' + url: 'https://tailwindcss.com/' +- name: 'React' + shield: 'https://img.shields.io/badge/react-^19.2.3-blue.svg' + url: 'https://reactjs.org/' +- name: 'Biome' + shield: 'https://img.shields.io/badge/biome-^1.8.3-blue.svg' + url: 'https://biomejs.dev/' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5cda57d..0910e64 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,5 +18,6 @@ jobs: node-version: '20.x' cache: 'npm' - run: npm install + - run: npm run format - run: npm run lint - run: npm run build --if-present diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f5cee4..b3c4f66 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,9 +17,9 @@ We welcome contributions to AlgoLens! Please follow these guidelines to ensure t * `npm run dev`: Starts the development server. * `npm run build`: Builds the application for production. * `npm run lint`: Lints the code. -* `npm run test`: Runs the tests. +* `npm run format`: Formats the code. ## Pull Requests -* Please ensure that your code is linted and that all tests pass before submitting a pull request. +* Please ensure that your code is formatted and linted before submitting a pull request. * Please provide a clear and concise description of the changes in your pull request. * Please link to any relevant issues in your pull request. diff --git a/README.md b/README.md index 6dfde8e..7fed8c8 100644 --- a/README.md +++ b/README.md @@ -1,55 +1,88 @@ # AlgoLens: A Frontend for Search Ranking Customization -[![Build Status](https://img.shields.io/github/actions/workflow/status/chirag127/AlgoLens-Search-Ranking-Configuration-Guide/ci.yml?style=flat-square)](https://github.com/chirag127/AlgoLens-Search-Ranking-Configuration-Guide/actions/workflows/ci.yml) -[![License](https://img.shields.io/badge/License-CC%20BY--NC%204.0-blue.svg?style=flat-square)](LICENSE) -[![GitHub Stars](https://img.shields.io/github/stars/chirag127/AlgoLens-Search-Ranking-Configuration-Guide?style=flat-square)](https://github.com/chirag127/AlgoLens-Search-Ranking-Configuration-Guide) - -**Star ⭐ this Repo if you find it valuable!** - ---- + + +

+ + License + + + Vite + + + TypeScript + + + Tailwind CSS + + + React + + + Biome + +

+ ## 🚀 Project Overview -AlgoLens is a modern, frontend-only application for viewing and managing Brave Goggles. It provides a clean, "Spatial-Adaptive" interface for browsing and inspecting `.goggle` files, which are custom search ranking configurations for the Brave Search ecosystem. +AlgoLens is a modern, **frontend-only** application for viewing and managing Brave Goggles. It provides a clean, "Spatial Glass" and "Bento Grid" inspired interface for browsing and inspecting `.goggle` files, which are custom search ranking configurations for the Brave Search ecosystem. + +This project is built with a cutting-edge tech stack and adheres to the Dec 2025 standards for frontend development, ensuring a high-velocity, zero-defect, and future-proof codebase. -This project is built with Vite, TypeScript, and Tailwind CSS, and it is designed to be deployed to static hosting platforms like GitHub Pages, Vercel, or Netlify. +## 🏛️ Architecture -## 🎯 Core Objective +AlgoLens follows a strict frontend-only architecture, running entirely in the browser. It leverages direct REST API calls to various AI providers, with users providing their own API keys at runtime. -The primary goal of AlgoLens is to provide a user-friendly interface for interacting with Brave Goggles. It aims to be a lightweight and performant tool for developers and power users who want to customize their search experience. +``` ++---------------------------------+ +| Browser (UI) | +| (React, Tailwind, Signals) | ++---------------------------------+ + | + | (User-provided API Keys) + v ++---------------------------------+ +| API Service Layer | +| (Cerebras, Gemini, Groq, etc.) | ++---------------------------------+ +``` -## ⚙️ Development Standards +## 🛠️ Tech Stack -### Prerequisites -* Node.js (v20.x LTS or newer) -* npm +- **Framework:** [Vite](https://vitejs.dev/) ^7.2.4 +- **Language:** [TypeScript](https://www.typescriptlang.org/) ^6.0.0-beta +- **UI:** [React](https://reactjs.org/) ^19.2.3, [Tailwind CSS](https://tailwindcss.com/) ^4.1.18 +- **State Management:** [@preact/signals-react](https://preactjs.com/guide/v10/signals/) +- **Linting/Formatting:** [Biome](https://biomejs.dev/) ^1.8.3 -### Setup & Installation +## ⚡ Quickstart -1. **Clone Repository:** - ```bash +1. **Clone the repository:** + ```sh git clone https://github.com/chirag127/AlgoLens-Search-Ranking-Configuration-Guide.git cd AlgoLens-Search-Ranking-Configuration-Guide ``` - -2. **Install Dependencies:** - ```bash +2. **Install dependencies:** + ```sh npm install ``` +3. **Run the development server:** + ```sh + npm run dev + ``` -### Core Scripts - -| Script | Description | -| :--- | :--- | -| `npm run dev` | Starts the local development server. | -| `npm run build` | Builds the application for production. | -| `npm run lint` | Lints the code. | +## ✨ Features +- **Goggle Viewer:** Browse and inspect `.goggle` files. +- **AI Integration:** Leverage multiple AI providers for advanced features (coming soon). +- **Modern UI:** A sleek, "Spatial Glass" and "Bento Grid" inspired interface. +- **Frontend-Only:** Runs entirely in the browser with no backend dependencies. ## 🤝 Contributing -Contributions are welcomed! Please review the detailed guidelines in [CONTRIBUTING.md](./CONTRIBUTING.md) before submitting pull requests. +Contributions are welcome! Please read the [CONTRIBUTING.md](./CONTRIBUTING.md) file for details on how to get started. ## 📄 License -This project is licensed under the **Creative Commons Attribution-NonCommercial 4.0 International License**. See the [LICENSE](./LICENSE) file for details. +This project is licensed under the [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/) license. diff --git a/.github/SECURITY.md b/SECURITY.md similarity index 100% rename from .github/SECURITY.md rename to SECURITY.md diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..dbe98e0 --- /dev/null +++ b/biome.json @@ -0,0 +1,16 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "formatter": { + "enabled": true, + "indentStyle": "space" + } +} diff --git a/package-lock.json b/package-lock.json index 591cf5d..57721c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,18 @@ "name": "temp-vite", "version": "0.0.0", "dependencies": { + "@preact/signals-react": "^2.0.1", "react": "^19.2.3", "react-dom": "^19.2.3" }, "devDependencies": { + "@biomejs/biome": "^1.8.3", "@tailwindcss/vite": "^4.1.18", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "tailwindcss": "^4.1.18", - "typescript": "~5.9.3", + "typescript": "^6.0.0-beta", "vite": "^7.2.4" } }, @@ -302,6 +306,170 @@ "node": ">=6.9.0" } }, + "node_modules/@biomejs/biome": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz", + "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==", + "dev": true, + "hasInstallScript": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "1.9.4", + "@biomejs/cli-darwin-x64": "1.9.4", + "@biomejs/cli-linux-arm64": "1.9.4", + "@biomejs/cli-linux-arm64-musl": "1.9.4", + "@biomejs/cli-linux-x64": "1.9.4", + "@biomejs/cli-linux-x64-musl": "1.9.4", + "@biomejs/cli-win32-arm64": "1.9.4", + "@biomejs/cli-win32-x64": "1.9.4" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz", + "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz", + "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz", + "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz", + "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz", + "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz", + "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz", + "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz", + "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", @@ -794,6 +962,33 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@preact/signals-core": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.12.1.tgz", + "integrity": "sha512-BwbTXpj+9QutoZLQvbttRg5x3l5468qaV2kufh+51yha1c53ep5dY4kTuZR35+3pAZxpfQerGJiQqg34ZNZ6uA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, + "node_modules/@preact/signals-react": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@preact/signals-react/-/signals-react-2.3.0.tgz", + "integrity": "sha512-g77rc7gTuPaoS5Lr80wjbN9P0t2U+YqJ6NG2krF5KLWLIoGn4uiByOv4bcZSJ41E4Nj50JLuXvdQEGlpU6cOug==", + "license": "MIT", + "dependencies": { + "@preact/signals-core": "^1.7.0", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + }, + "peerDependencies": { + "react": "^16.14.0 || 17.x || 18.x || 19.x" + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.53", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz", @@ -1433,6 +1628,27 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, "node_modules/@vitejs/plugin-react": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.2.tgz", @@ -1527,6 +1743,13 @@ "dev": true, "license": "MIT" }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, "node_modules/debug": { "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", @@ -2224,9 +2447,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.0-dev.20251223", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.0-dev.20251223.tgz", + "integrity": "sha512-/mnCnGVmxLd1Rda5kyMYaPSYpg/YkhmqTLJn63iNLXt2VdOg/vXE84F8CZTKeVJFh5rkrfZj6lqKrTEN1+CL9Q==", "dev": true, "license": "Apache-2.0", "bin": { @@ -2268,6 +2491,15 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/vite": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", diff --git a/package.json b/package.json index 7514358..af8d785 100644 --- a/package.json +++ b/package.json @@ -7,17 +7,21 @@ "dev": "vite", "build": "tsc && vite build", "preview": "vite preview", - "predev": "node scripts/generate-goggle-list.mjs", - "prebuild": "node scripts/generate-goggle-list.mjs" + "lint": "biome lint .", + "format": "biome format --write ." }, "devDependencies": { + "@biomejs/biome": "^1.8.3", "@tailwindcss/vite": "^4.1.18", + "@types/react": "^19.2.7", + "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^5.1.2", "tailwindcss": "^4.1.18", - "typescript": "~5.9.3", + "typescript": "^6.0.0-beta", "vite": "^7.2.4" }, "dependencies": { + "@preact/signals-react": "^2.0.1", "react": "^19.2.3", "react-dom": "^19.2.3" } diff --git a/scripts/generate-goggle-list.mjs b/scripts/generate-goggle-list.mjs deleted file mode 100644 index 0487801..0000000 --- a/scripts/generate-goggle-list.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import fs from 'fs'; -import path from 'path'; - -const gogglesDir = path.resolve(process.cwd(), 'goggles'); -const output = path.resolve(process.cwd(), 'src/goggles.json'); - -const files = fs.readdirSync(gogglesDir).filter(f => f.endsWith('.goggle')); -fs.writeFileSync(output, JSON.stringify(files)); diff --git a/src/App.tsx b/src/App.tsx index ff67abc..72ba4e8 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,50 +1,62 @@ -import { useState, useEffect } from 'react'; -import './style.css'; -import goggles from './goggles.json'; +import { signal, effect } from "@preact/signals-react"; +import goggles from "./goggles.json"; +import { ApiKeyManager } from "./components/ApiKeyManager"; -function App() { - const [selectedGoggle, setSelectedGoggle] = useState(null); - const [goggleContent, setGoggleContent] = useState(''); +const selectedGoggle = signal(null); +const goggleContent = signal(""); - useEffect(() => { - if (selectedGoggle) { - fetch(`/goggles/${selectedGoggle}`) - .then((res) => res.text()) - .then((text) => setGoggleContent(text)); - } - }, [selectedGoggle]); +effect(() => { + if (selectedGoggle.value) { + fetch(`/goggles/${selectedGoggle.value}`) + .then((res) => res.text()) + .then((text) => (goggleContent.value = text)); + } +}); +function App() { return ( -
-
-

AlgoLens

-
-
-