Skip to Content
Polyant is open source under AGPL-3.0 — star us on GitHub.
ReferenceDevelopment Workflow

Development Workflow

Day-to-day commands and conventions for working on Polyant. Read Getting Started first if you have not yet run the project locally.

Prerequisites

  • Node.js 22+ (LTS recommended)
  • npm 10+ (ships with Node 22)
  • Docker + Docker Compose (for PostgreSQL with pgvector)
  • A POSIX-style shell (bash, zsh, fish)

Optional but recommended:

  • An OpenAI or Anthropic API key (the engine needs at least one for LLM calls)
  • An IDE with TypeScript support (VS Code, Cursor, etc.)

Setup

git clone https://github.com/polyant-ai/polyant.git cd polyant cp .env.example .env # then edit secrets npm install # installs all workspaces docker compose up -d # starts postgres on :5432 npm run db:migrate # creates schema + seeds demo-agent

Run

All commands work from the monorepo root.

# Engine (NestJS) — OpenAI-compatible + management API on :4000 npm run dev # alias: npm run dev:engine # Admin panel (Next.js) on :3000 npm run dev:web

Per-workspace commands use -w:

npm run dev -w @polyant/engine npm run build -w @polyant/web

Test

npm run test:unit # vitest unit tests (engine) npm run test:integration # database-backed integration tests npm run test:functional # end-to-end pipeline tests npm test # all of the above npm run typecheck # tsc --noEmit on all workspaces npm run lint # eslint on all workspaces

CI runs typecheck + lint + test on every PR. Run them locally before pushing.

Database

Drizzle ORM manages schema. Migrations live in packages/engine/src/database/migrations/.

npm run db:generate # generate a migration from schema diff npm run db:migrate # apply pending migrations npm run db:studio # open Drizzle Studio GUI

Note: npx drizzle-kit generate does not work in this repo because of an ESM incompatibility. Use npm run db:generate (which calls drizzle-kit via tsx) or write incremental migrations by hand. See CLAUDE.md  → “drizzle-kit with ESM” caveat.

Adding a new tool

Tools self-register at boot. The pattern is described in detail in CLAUDE.md  → “Tool registry”.

  1. Create packages/engine/src/agents/tools/<your-tool>.tool.ts.
  2. Call registerTool({ name, description, inputSchema, execute }) at module top level.
  3. Restart the engine — loadAllTools() auto-discovers the file.
  4. Enable the tool on an instance via the admin panel Tools tab (or PATCH /api/instances/:slug/tools).

For canonical, in-tree examples see any *.tool.ts file under packages/engine/src/agents/tools/ — every registered tool lives there and follows the same pattern.

Adding a new skill

Skills live in the skills + skill_versions DB tables — never on disk.

  • Through the UI: admin panel → Skills library → New skill, then attach it to an instance via the Skills tab.
  • Through the API: POST /api/skills then PATCH /api/instances/:slug/skills to enable it.

See Skill Frontmatter for the SKILL.md format (frontmatter + body).

Branching and commits

  • Branch off main: feat/<short-name>, fix/<short-name>, etc.
  • One logical change per commit.
  • Conventional Commits format:
    feat(engine): add Discord channel adapter fix(web): correct sidebar collapse on mobile docs: add deployment recipe for Fly.io
  • Sign off every commit with the DCO (git commit -s). See CONTRIBUTING.md .

Pull request

  1. Push your branch and open a PR against main.
  2. The PR template asks for: summary, motivation, test plan.
  3. Make sure CI passes (typecheck, lint, test).
  4. Keep PRs focused — under ~400 lines of diff is easier to review.
  5. Address review feedback in new commits (no force-pushes during review).
  6. A maintainer will squash-merge once approved.

Where to look next

Last updated on