Thank you for your interest in contributing to Cognito AI! This document provides guidelines and instructions for contributing to the project.
- Code of Conduct
- Getting Started
- How to Contribute
- Development Workflow
- Coding Standards
- Commit Guidelines
- Pull Request Process
- Reporting Bugs
- Suggesting Features
By participating in this project, you agree to maintain a respectful and inclusive environment for everyone.
-
Fork the Repository
# Click the 'Fork' button on GitHub -
Clone Your Fork
git clone https://github.com/YOUR_USERNAME/cognito-ai.git cd cognito-ai -
Add Upstream Remote
git remote add upstream https://github.com/codewarnab/cognito-ai.git
-
Install Dependencies
pnpm install
-
Create a Branch
git checkout -b feature/your-feature-name
For detailed setup instructions, see SETUP.md.
- 🐛 Bug Fixes: Fix issues and bugs
- ✨ New Features: Add new functionality
- 📝 Documentation: Improve or add documentation
- 🎨 UI/UX: Enhance user interface and experience
- ♻️ Refactoring: Improve code quality
- ✅ Tests: Add or improve tests
- 🔧 Tooling: Improve development tools
git fetch upstream
git checkout master
git merge upstream/mastergit checkout -b feature/my-new-feature
# or
git checkout -b fix/bug-description- Write clean, maintainable code
- Follow the coding standards (see below)
- Add tests if applicable
- Update documentation as needed
# Start development server (runs only the extension)
pnpm dev
# Start all packages in development mode
pnpm dev:all
# Build for production (all packages)
pnpm build
# Type check (all packages)
pnpm type:checkgit add .
git commit -m "feat: add new feature"See Commit Guidelines for commit message format.
git push origin feature/my-new-feature- Go to your fork on GitHub
- Click "New Pull Request"
- Select your feature branch
- Fill out the PR template
- Submit the pull request
- Use TypeScript with strict type checking
- Use Prettier for code formatting (sort imports plugin is included)
- Prefer
constoverlet; avoidvar - Use meaningful variable and function names
- Add JSDoc comments for complex functions when helpful
This extension uses React 19 with important changes:
In React 19, ref is passed as a regular prop instead of using forwardRef:
// ✅ React 19 - ref as prop
interface Props {
ref?: React.RefObject<HTMLDivElement | null>;
}
function MyComponent({ ref, ...props }: Props) {
return <div ref={ref} {...props} />;
}
// ❌ Old React 18 pattern (still works but not preferred)
const MyComponent = forwardRef<HTMLDivElement, Props>((props, ref) => {
return <div ref={ref} {...props} />;
});useRef<T>(null) now returns RefObject<T | null> instead of RefObject<T>:
// ✅ React 19 - explicit null in type
const inputRef = useRef<HTMLInputElement | null>(null);- Use functional components with hooks
- Keep components small and focused
- Use proper prop typing with TypeScript
- Follow React best practices
CRITICAL: Selective Subscriptions Required
Never subscribe to the entire store with useStore(). Always use individual selectors:
// ❌ BAD - Causes infinite re-render loops
const store = useToolsStore();
// ✅ GOOD - Selective subscriptions for each value
const showModal = useToolsStore((s) => s.showModal);
const setShowModal = useToolsStore((s) => s.setShowModal);When reading data from the DOM that will be sent to AI or backend:
- NEVER capture sensitive input values (passwords, credit cards, SSN, etc.)
- Always check if an input is sensitive before reading
input.value - Sensitive types:
password - Sensitive autocomplete:
cc-number,cc-exp,cc-csc,current-password,new-password - Sensitive name/id patterns:
/password|card|cvv|csc|ssn|secret|pin/i
// SECURITY: Stripping value from sensitive fields to prevent PII leakage to AI
const value = isSensitiveInput(input) ? undefined : input.value;NEVER write broad CSS selectors that can match elements across unrelated components:
/* ❌ BAD - Too broad, affects all spans inside any .group element */
.group:hover span {
max-width: 50px;
}
/* ✅ GOOD - Scoped to specific component */
.my-feature-btn:hover span {
max-width: 50px;
}CRITICAL: Always use the centralized ENV module instead of directly accessing import.meta.env:
// ✅ CORRECT - Use centralized ENV module
import { ENV } from '@/utils/env';
const workerUrl = ENV.ELEVENLABS_WORKER_URL;
// ❌ WRONG - Never access directly
const workerUrl = import.meta.env.WXT_ELEVENLABS_WORKER_URL;All createLogger calls MUST include a category as the second argument:
import { createLogger } from '~logger';
const log = createLogger('FeatureName', 'CATEGORY');- Use PascalCase for React component files:
MyComponent.tsx - Use camelCase for hooks and utilities:
useTabContext.ts,modelSettings.ts - Keep directory names consistent and descriptive; avoid mixing styles within a module
- Avoid deep relative paths like
../../..in imports - Use path aliases defined in
tsconfig.json(specifically forapps/extension):~*→./src/*(e.g.,import { something } from '~/utils/helper')@/*→./src/*(e.g.,import { handleAPIError } from '@/utils/apiErrorHandler',@/components/...,@/ai/...)@assets/*→./assets/*(e.g.,import icon from '@assets/icon.png')~logger→./src/logger(e.g.,import { createLogger } from '~logger')
Use @cognito/shared for shared types and constants between packages:
// Import types
import type { WriteTone, RewritePreset, SummaryType } from '@cognito/shared';
// Import constants
import { TONE_INSTRUCTIONS, PRESET_PROMPTS } from '@cognito/shared';// 1. Imports
import React from 'react'
import { useState } from 'react'
// 2. Types/Interfaces
interface MyComponentProps {
title: string
}
// 3. Component
export const MyComponent: React.FC<MyComponentProps> = ({ title }) => {
// 4. Hooks
const [state, setState] = useState()
// 5. Event handlers
const handleClick = () => {
// ...
}
// 6. Render
return <div>{title}</div>
}We follow the Conventional Commits specification.
<type>(<scope>): <subject>
<body>
<footer>
Since this is a monorepo, please specify the scope of the change:
extensionwebappdocssharedbackend-cloudflarebackend-vercelrepo(for root level changes)
feat: A new featurefix: A bug fixdocs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoringperf: Performance improvementstest: Adding or updating testschore: Maintenance tasksci: CI/CD changes
feat(ai): add support for new Gemini model
fix(sidepanel): resolve memory leak in chat component
docs: update setup instructions
style: format code with prettier
refactor(utils): simplify token counting logic- Update Documentation: Ensure all relevant documentation is updated
- Add Tests: Include tests for new features or bug fixes
- Run Tests: Ensure all tests pass
- Update CHANGELOG: Add your changes to the unreleased section (if applicable)
- Describe Your Changes: Provide a clear description in the PR
- Link Issues: Reference related issues (e.g., "Fixes #123")
- Wait for Review: A maintainer will review your PR
- Address Feedback: Make requested changes if needed
- Merge: Once approved, your PR will be merged
Use the same format as commit messages:
feat: add new AI model support
fix: resolve sidepanel crash on startup
- Check the existing issues
- Try to reproduce the bug in the latest version
- Collect relevant information (error messages, screenshots, etc.)
- Go to Issues
- Choose "Bug Report" template
- Fill in all required information:
- Description: Clear description of the bug
- Steps to Reproduce: Detailed steps to reproduce
- Expected Behavior: What should happen
- Actual Behavior: What actually happens
- Environment: OS, browser version, extension version
- Screenshots: If applicable
- Error Logs: Console errors or stack traces
- Check if the feature has already been suggested
- Go to Issues
- Choose "Feature Request" template
- Provide:
- Use Case: Why this feature is needed
- Proposed Solution: How it should work
- Alternatives: Other approaches considered
- Additional Context: Any other relevant information
If you have questions about contributing:
- Open a Discussion
- Check the Documentation
- Review the Setup Guide
By contributing to Cognito AI, you agree that your contributions will be licensed under the BUSL-1.1 License.
Thank you for contributing to Cognito AI! 🎉