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

Development Workflow

On this page

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 24 (the active LTS, named in .nvmrc)
  • npm 11 (ships with Node 24)
  • 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 # schema (no agent is seeded)

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 test # tests in every workspace 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 are discovered at boot by scanning a directory.

  1. Create packages/engine/src/agents/tools/<your-tool>.tool.ts.
  2. export default defineTool({ name, description, parameters, execute }), importing defineTool from @polyant-ai/plugin-sdk. This is the only shape the loader recognises - a file with any other default export is skipped with a console warning, and the tool silently does not exist.
  3. Restart the engine - loadAllTools() auto-discovers the file.
  4. Enable the tool on an agent from its Tools section (or PATCH /api/instances/:slug/tools).

For canonical, in-tree examples see any *.tool.ts file under packages/engine/src/agents/tools/. The full walkthrough, including the strict-mode schema rules and the runtime context, is in Add a Tool.

Adding a new skill

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

  • Through the UI: admin panel → Skills → New skill, then attach it to an agent from its Skills section.
  • Through the API: POST /api/organizations/:orgSlug/skills to create it, then PATCH /api/instances/:slug/skills to enable it on an agent. That second call takes the complete set of enabled skill names, not a delta.
  • Either way the skill also has to be assigned to the agent’s workspace before the runtime will serve it - see What a workspace may draw on.

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