CONTRIBUTING.md
Rama main · réplica de lectura del repositorio original.
# Contributing to Polyant
Thank you for your interest in contributing! This document covers everything you need to get started.
## Prerequisites
- **Node.js 24+** — `node --version` should show v24 or higher
- **Docker & Docker Compose** — used to run PostgreSQL with pgvector
- **PostgreSQL 16 client** (optional, for direct DB access)
## Local Setup
### 1. Clone the repository
```bash
git clone https://github.com/polyant-ai/polyant.git
cd polyant
```
### 2. Install dependencies
Always install from the monorepo root — never inside a package directory.
```bash
npm install
```
### 3. Configure environment
```bash
cp .env.example .env
```
Edit `.env` and set at minimum:
| Variable | Description |
|----------|-------------|
| `ENCRYPTION_KEY` | 32-byte hex key for instance secrets — generate with `openssl rand -hex 32` |
| `AUTH_SECRET` | Auth.js JWE encryption secret — generate with `openssl rand -hex 32` |
| `AUTH_INTERNAL_SECRET` | Shared secret for web→engine internal calls — generate with `openssl rand -hex 32`. Without it nobody can sign in to the panel |
| `INITIAL_ADMIN_PASSWORD` | Seeds the first admin account at boot — without it no admin is created. The panel asks for a new password at the first sign-in |
| `INITIAL_ADMIN_EMAIL` | Email of that account (optional, defaults to `administrator@local`) |
| `POSTGRES_PASSWORD` | Password of the Docker database. The sample value is `changeme`; if you change it, put the same password in `DATABASE_URL` |
Next.js does not read the monorepo root `.env`, so create `packages/web/.env.local`
with the web-facing values:
```bash
AUTH_SECRET=<same value as .env>
AUTH_INTERNAL_SECRET=<same value as .env>
AUTH_TRUST_HOST=true
DATABASE_URL=postgresql://polyant:changeme@localhost:5432/polyant # same password as .env
NEXT_PUBLIC_API_URL=http://localhost:4000
INTERNAL_ENGINE_URL=http://localhost:4000
```
### 4. Start infrastructure
Docker Compose takes `POSTGRES_PASSWORD` from `.env`, so run this after step 3:
```bash
docker compose up -d --wait
```
This starts PostgreSQL 16 with the pgvector extension on port 5432 and returns once the
database accepts connections.
### 5. Run database migrations
```bash
npm run db:migrate
```
### 6. Start development servers
```bash
# Terminal 1 — engine (NestJS 12, port 4000)
npm run dev
# Terminal 2 — admin panel (Next.js, port 3000)
npm run dev:web
```
Open the admin panel at `http://localhost:3000`, sign in with `INITIAL_ADMIN_EMAIL` /
`INITIAL_ADMIN_PASSWORD`, choose a new password when the panel asks, and create your
first instance. Set its provider keys in the **Model** section.
## Project Structure
```
polyant/
├── packages/
│ ├── engine/ # @polyant/engine — NestJS AI runtime + API
│ │ └── src/
│ │ ├── agents/ # Supervisor, tool registry, sub-agent delegation
│ │ ├── ai-gateway/ # Provider-agnostic LLM abstraction (tier-based)
│ │ ├── channels/ # Telegram, Slack, WhatsApp adapters
│ │ ├── memory/ # pgvector embeddings + hybrid search
│ │ ├── knowledge/ # Per-instance document store + retrieval
│ │ ├── hooks/ # Conversation lifecycle hooks
│ │ ├── room/ # Event-driven proactive agent workspace
│ │ ├── instances/ # Instance CRUD, secrets, config resolver
│ │ ├── skills/ # Global skill library CRUD
│ │ ├── authz/ # Roles, permissions, tenancy scoping
│ │ └── server/ # NestJS controllers (REST + OpenAI-compat)
│ └── web/ # @polyant/web — Next.js admin panel
│ └── src/app/
│ ├── (auth)/ # Sign-in (email + password)
│ └── (admin)/ # Protected admin routes
├── examples/ # Minimal working examples (instances, skills)
└── docker-compose.yml # PostgreSQL + pgvector
```
See [Architecture](https://docs.polyant.ai/concepts/architecture) for a full technical reference (source: [polyant-ai/docs](https://github.com/polyant-ai/docs)).
## Commands
Every command runs from the monorepo root and delegates to the right workspace.
| Command | Description |
|---------|-------------|
| `npm run dev` | Start engine with hot reload (tsx watch, port 4000) |
| `npm run dev:web` | Start Next.js admin panel (port 3000) |
| `npm run build` | Build all packages |
| `npm start` | Run engine from compiled output |
| `npm run db:generate` | Generate Drizzle migrations from schema |
| `npm run db:migrate` | Apply pending migrations |
| `npm run db:studio` | Open Drizzle Studio GUI |
| `npm test` | Run all tests |
| `npm run test:unit` | Unit tests only (no DB required) |
| `npm run test:integration` | Integration tests (requires PostgreSQL) |
| `npm run lint` | ESLint all packages |
| `npm run typecheck` | TypeScript check all packages |
## Development Workflow
### Before starting
- For non-trivial features, open an issue first to discuss the approach.
- For bugs, check existing issues before filing a new one.
### Making changes
1. Fork the repository and create a branch from `develop`:
```bash
git checkout develop
git checkout -b feat/my-feature
```
`develop` is the integration branch; `main` only ever holds released code and is
updated by a release or a hotfix PR. Base your work on `develop` unless you are
fixing something that is broken in the current release.
2. Make your changes following the conventions below.
3. Run the checks before pushing:
```bash
npm run typecheck # must pass with 0 errors
npm run lint # must pass with 0 errors
npm run test:unit # all tests must pass
```
### Commit conventions
This project follows [Conventional Commits](https://www.conventionalcommits.org/):
```
type(scope): short description
```
Valid types: `feat`, `fix`, `refactor`, `test`, `docs`, `chore`, `perf`, `ci`
Examples:
- `feat(tools): add httpRequest tool with SSRF protection`
- `fix(channels): handle Telegram webhook reconnection`
- `docs(readme): update quick start for Docker setup`
### Sign your work (DCO)
Polyant uses the [Developer Certificate of Origin](https://developercertificate.org/)
for contributions, instead of a Contributor License Agreement.
Every commit must include a `Signed-off-by` line. Sign your commits with:
git commit -s -m "feat: my change"
This appends a line like:
Signed-off-by: Your Name <your.email@example.com>
The `-s` flag uses your `git config user.name` and `user.email`. If you forgot
to sign a previous commit, amend it with:
git commit --amend -s --no-edit
Or rebase to add sign-off to a range of commits:
git rebase -i --exec "git commit --amend -s --no-edit" main
The DCO check is enforced by GitHub Actions on every pull request. PRs without
sign-off cannot be merged.
### Pull Request process
1. Open a PR against `develop` with a clear title (Conventional Commits format). CI runs on both `main` and `develop`.
2. Fill in the PR description: what changes, why, and how to test.
3. CI must pass (lint + typecheck + tests).
4. All commits must be signed off (see DCO section above).
5. At least one maintainer review is required before merge.
6. PRs are squash-merged to keep history clean.
## Code Conventions
- **Engine imports** — relative runtime imports under `packages/engine` use `.js`.
- **Web imports** — relative imports under `packages/web/src` are extensionless.
- **Tools and hooks** — default-export their SDK definition; follow the nearest existing
module for other export and naming conventions.
- **Configuration and secrets** — use the owning resolver/store. Never hardcode secrets.
- **Framework-first** — instance behaviour lives in per-instance data, never code branches.
See [`CLAUDE.md`](CLAUDE.md) and the matching path-scoped rule under `.claude/rules/`.
## Adding a New Tool
1. Create `packages/engine/src/agents/tools/my-tool.tool.ts`.
2. Default-export `defineTool({ name, description, parameters, execute })` from
`@polyant-ai/plugin-sdk`. `parameters` is a **static** Zod schema (it must not read
`ctx`); the business logic lives in `execute(input, ctx)`.
3. The loader collects the default export at boot and syncs the `tools` table — no
imports to update elsewhere.
Domain-specific tools belong in an external **plugin** repo rather than in the engine.
See [docs/plugins.md](docs/plugins.md) and the
[Plugins & the SDK](README.md#plugins--the-sdk) section of the README.
## Adding a New Skill
Skills live in the database. Use the management API or admin panel to create them. See [Architecture](https://docs.polyant.ai/concepts/architecture) for the skill system design.
## Running Tests
```bash
npm run test:unit # fast, no DB required
npm run test:integration # requires a running PostgreSQL instance
```
## Reporting Security Issues
Please **do not** open a public GitHub issue for security vulnerabilities. See [SECURITY.md](SECURITY.md) for the responsible-disclosure process and contact details.
## License
By contributing, you agree that your contributions will be licensed under the [AGPL-3.0 License](LICENSE).