Ctrl K
ComunidadGuías…

CONTRIBUTING.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# 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).