Thank you for your interest in contributing to Pilo! This document provides guidelines and instructions for contributing to the project.
- Before You Start
- Prerequisites
- Development Setup
- Project Structure
- Development Workflow
- Testing
- Building
- Code Style
- Making Changes
- Submitting Your Contribution
- Review Process
- Your First Contribution
- Code of Conduct
- Questions
Before starting work, check if there is already an open issue for what you would like to contribute. If there is not, consider opening one to discuss your proposed changes with the maintainers.
Pilo is an AI-powered web automation library and CLI tool structured as a pnpm monorepo. Familiarize yourself with the project's goals and architecture before making significant changes.
- For bug reports and feature requests, open an issue
- For questions and discussions, use the appropriate communication channels
- For security issues, follow our security disclosure policy
| Tool | Version | Notes |
|---|---|---|
| Node.js | ^22.0.0 |
Required. Use nvm or fnm to manage versions. |
| pnpm | 9.0.0 |
Required. Do not use npm or yarn for this project. |
If you do not have pnpm installed, use Corepack (bundled with Node.js 16+):
corepack enable
corepack prepare pnpm@9.0.0 --activateOr install directly:
npm install -g pnpm@9.0.0Verify your versions:
node --version # should be 22.x
pnpm --version # should be 9.0.0# 1. Fork the repository, then clone your fork
git clone https://github.com/<your-username>/pilo.git
cd pilo
# 2. Install all workspace dependencies
pnpm install
# 3. Install browser automation drivers (needed for Playwright-based tests and CLI use)
pnpm playwright install
# 4. Verify the baseline is clean
pnpm run checkpnpm pilo config initThis stores your configuration at ~/.config/pilo/config.json.
pilo/
├── packages/
│ ├── core/ # pilo-core: automation engine and config system
│ ├── cli/ # pilo-cli: CLI commands and config integration
│ ├── server/ # pilo-server: Hono-based server
│ └── extension/ # pilo-extension: WXT/React browser extension
├── scripts/ # Build, release, and CI scripts
├── dist/ # Assembled output (root build only, not committed)
├── package.json # @tabstack/pilo workspace root + published package
└── pnpm-workspace.yaml
| Package | npm name | Description |
|---|---|---|
packages/core |
pilo-core |
Core automation library. Browser-safe subset via core.ts; full Node.js API via index.ts. |
packages/cli |
pilo-cli |
CLI entry point, commands, and config integration. |
packages/server |
pilo-server |
Hono-based server component. |
packages/extension |
pilo-extension |
WXT-based browser extension with React UI. |
| root | @tabstack/pilo |
Published npm package: bundles core + CLI + pre-built extension. |
Before and after making changes, run the full check to confirm nothing is broken:
pnpm run checkThis chains typecheck (which includes pre-test bundle generation, formatting check, and per-package typechecks) followed by all tests.
# 1. Format code
pnpm run format
# 2. Typecheck all packages (also checks formatting)
pnpm run typecheck
# 3. Run all tests
pnpm -r run testpnpm pilo run "task description"
pnpm pilo config init
pnpm pilo config set <key> <value>
pnpm pilo config get <key>
pnpm pilo config list
pnpm pilo config show
pnpm pilo config unset <key>
pnpm pilo config reset
pnpm pilo extension install chrome
pnpm pilo extension install firefox [--tmp]# Hot-reloading dev mode (Chrome)
pnpm run dev:extension -- --chrome
# Hot-reloading dev mode (Firefox)
pnpm run dev:extension -- --firefox
# With a temporary browser profile (clean state on every start)
pnpm run dev:extension -- --chrome --tmp
pnpm run dev:extension -- --firefox --tmppnpm run dev:serverAll packages use Vitest for unit tests. The extension additionally uses Playwright for end-to-end tests.
Test files live in each package's test/ directory, mirroring the src/ structure.
# All packages
pnpm -r run test
# Specific package
pnpm --filter pilo-core run test
pnpm --filter pilo-cli run test
pnpm --filter pilo-server run test
pnpm --filter pilo-extension run test
# Extension end-to-end tests
pnpm --filter pilo-extension run test:e2e # headed
pnpm --filter pilo-extension run test:e2e:headless # headless- Use
vi.mock()from Vitest for mocking. - Write tests for new features and bug fixes.
- Ensure all existing tests pass before submitting.
- Add both unit tests and integration tests where appropriate.
# Full production build (core + extension, then compiles into dist/)
pnpm run build
# Build all packages individually
pnpm -r run build
# Clean all build artifacts
pnpm run cleanThe root build assembles the published package at dist/. This includes the core library, CLI binary, and pre-built extension for both Chrome and Firefox.
All code is formatted with Prettier. Configuration lives at the root .prettierrc only; do not add package-level Prettier config.
pnpm run format # Format all files
pnpm run format:check # Check without modifyingFormat is enforced in CI. Unformatted code will fail the typecheck step.
- Use the latest stable TypeScript features.
- Avoid
any. Useunknownwith type narrowing where the type is genuinely unknown. - Keep functions focused and modular.
- Prioritize readability over cleverness.
- No barrel imports except
index.tsandcore.tsinpackages/core, andbrowser/ariaTree/index.ts. Do not create new barrel files. - Cross-package references use the
workspace:*protocol, not relativefile:paths. - Extension imports: The extension must import from
pilo-core/core(notpilo-core) to avoid pulling in Node.js-only dependencies. - Shared dependencies: All packages must use the same version of any shared dependency. CI enforces this via
scripts/check-dep-versions.mjs.
Use descriptive branch names that follow this pattern:
feature/short-description- For new featuresfix/short-description- For bug fixesdocs/short-description- For documentation changesrefactor/short-description- For code refactoringtest/short-description- For test additions or improvements
Example: feature/add-chrome-extension-support
Write clear, descriptive commit messages:
- Use the imperative mood ("Add feature" not "Added feature")
- Keep the first line under 72 characters
- Add a blank line followed by a detailed description if needed
- Reference issue numbers when applicable (e.g., "Fix #123")
Example:
Add support for Chrome extension automation
Implement browser extension detection and interaction capabilities.
This allows agents to interact with Chrome extensions programmatically.
Fixes #123
Before committing, scan for accidentally included secrets:
# Install gitleaks (macOS)
brew install gitleaks
# Scan staged changes before each commit
gitleaks protect -v# Enable automatic scanning before every commit
git config core.hooksPath .githooks
# Disable
git config --unset core.hooksPathNever commit real API keys. Use obviously fake values like "fake-key-123" in tests.
- Fork and Clone: Fork the repository and clone it locally
- Create a Branch: Create a new branch for your changes
- Make Changes: Implement your changes following the guidelines above
- Test: Ensure all tests pass and add new tests as needed
- Check: Run
pnpm run checkto confirm everything passes - Commit: Commit your changes with clear commit messages
- Push: Push your branch to your fork
- Open a Pull Request: Open a PR against the main repository
Your PR description should include:
- What: A clear description of what you have changed
- Why: The motivation for the change (link to issue if applicable)
- How: An overview of your implementation approach
- Testing: What testing you have done
- Screenshots: If applicable, include before/after screenshots
Example template:
## Description
Brief description of the changes
## Motivation
Why is this change necessary? What problem does it solve?
## Implementation
How did you implement the solution?
## Testing
- [ ] Unit tests added/updated
- [ ] Integration tests added/updated
- [ ] Manual testing completed
## Related Issues
Fixes #123- Maintainers will review your PR and may request changes
- Be responsive to feedback and questions
- Reviews may take time; please be patient
- Your PR may go through multiple rounds of review
Reviewers will check for:
- Code quality and adherence to project standards
- Test coverage and quality
- Documentation updates (if applicable)
- Backward compatibility
- Performance implications
- Security considerations
- Address review feedback by pushing new commits to your branch
- Respond to review comments to clarify your approach
- Mark conversations as resolved once addressed
New to open source? Here are some ways to get started:
Look for issues labeled good first issue or beginner-friendly. These are specifically curated for newcomers.
Documentation improvements are always welcome and a great way to learn the project:
- Fix typos or clarify unclear sections
- Add examples or tutorials
- Improve code comments
Start with small, well-defined bug fixes to get familiar with the contribution process.
Don't hesitate to ask questions on issues or in discussions. The community is here to help!
This project adheres to a Code of Conduct that all contributors are expected to follow. Please read CODE_OF_CONDUCT.md before contributing.
Key points:
- Be respectful and inclusive
- Welcome diverse perspectives
- Accept constructive criticism gracefully
- Focus on what is best for the community
- General Questions: Open a discussion or issue
- Bug Reports: Open an issue with steps to reproduce
- Feature Requests: Open an issue describing your idea
- Security Issues: Follow the security disclosure policy
If you are stuck:
- Check existing documentation and issues
- Search for similar questions or problems
- Ask in the appropriate channel with specific details
- Be patient and respectful when awaiting responses
By contributing to Pilo, you agree that your contributions will be licensed under the same license as the project.
Thank you for contributing to Pilo! Your efforts help make browser automation and AI agents more accessible and powerful for everyone.