Ctrl K
ComunidadGuías…

CLAUDE.md

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

Archivo original ↗Preguntar a KiBot
# Polyant

Polyant is an open-source, domain-agnostic platform for building AI assistants. It is an
npm-workspaces monorepo with a NestJS runtime (`packages/engine`) and a Next.js admin panel
(`packages/web`). Assistant behaviour comes from PostgreSQL data, not instance-specific
code or files.

## Working agreement

- The user's current request overrides repository guidance when they conflict.
- Inspect the relevant code, tests, package manifest, and recent history before editing.
- Prefer the smallest change at the shared root cause. Do not add speculative abstractions.
- Preserve unrelated changes in dirty worktrees. Never discard or overwrite work you did
  not create.
- Do not push, open or merge a PR, publish, tag, or release unless the user explicitly asks.
- Before claiming completion, run the narrowest relevant checks and report anything that
  could not run.

## Sources of truth

Use this order when documentation disagrees:

1. Executable code, schema, migrations, tests, and CI.
2. Package manifests and lockfile for versions and commands.
3. Current ADRs and reference documentation.
4. This file and path-scoped rules.
5. Historical prose and Git history.

Do not preserve a contradicted statement merely because it appears in an old plan or spec.
Temporary implementation plans do not belong in the repository after the work lands.
Record durable architectural decisions in `docs/adr/`; Git is the archive.

## Commands

Run dependency installation from the repository root.

```bash
npm run dev                 # engine
npm run dev:web             # web panel
npm run build               # all workspaces
npm run lint
npm run typecheck
npm test
npm run test:unit
npm run test:integration
npm run db:generate
npm run db:migrate
docker compose up -d
```

Use workspace targeting for narrow checks, for example:

```bash
npm run typecheck -w @polyant/engine
npm run test -w @polyant/web
npx vitest run --root packages/engine path/to/file.test.ts
```

The scripts in `package.json` are authoritative. Do not copy dependency versions into
instructions; read the relevant manifest.

## Repository map

```text
packages/engine/src/
  index.ts                 boot sequence and pipeline wiring
  agents/                  supervisor and built-in tools
  ai-gateway/              provider-independent chat boundary
  embeddings-gateway/      provider-independent embeddings
  instances/               instance data and configuration resolution
  hooks/                   lifecycle hook definitions and runner
  plugin-system/           plugin discovery and loading
  channels/                channel adapters
  server/                  NestJS HTTP bridge
  database/                client and migrations

packages/web/src/
  app/                     Next.js App Router routes
  components/ui/           source-owned shadcn components
  lib/api.ts               web-to-engine request boundary
  lib/tenant/              URL and workspace resolution
```

Further references:

- `README.md` and `CONTRIBUTING.md`: product setup and contribution workflow.
- `docs/plugins.md`: public plugin contract.
- `docs/UPGRADING.md`: upgrade guidance.
- `docs/adr/`: current architectural decisions.
- `.claude/skills/backend-architecture/SKILL.md`: backend change workflow.
- `.claude/skills/frontend-design-system/SKILL.md`: frontend change workflow.
- `.claude/skills/plugin-authoring/SKILL.md`: tool, hook, and plugin authoring.

## Architecture boundaries

- Keep the product domain-agnostic. Prompts, skills, tool enablement, secrets, channels,
  and assistant settings are per-instance database data.
- `packages/engine/src/server/` is the NestJS HTTP bridge. Runtime/domain logic stays in
  domain modules and must not depend on HTTP request or response objects.
- Components request the AI gateway by capability/tier, not by hard-coded provider model.
  Keep direct AI SDK calls inside `ai-gateway/providers/base.ts`.
- A built-in tool is a `*.tool.ts` default export created with `defineTool(...)`; a built-in
  hook is a `*.hook.ts` default export created with `defineHook(...)`. Discovery happens at
  boot. See `docs/plugins.md` before changing this contract.
- `replyHandled` and `replyText` are reserved tool-result fields because the supervisor may
  use them as the user-visible reply.
- Post-response work is asynchronous and commit-on-success. Preserve the abort gate and
  the distinction between records written before and after it.
- All web-to-engine API calls go through `request<T>()` in `packages/web/src/lib/api.ts`,
  which attaches the workspace slug. A component-level `fetch` can target the wrong tenant.
- Outbound requests that use an Undici dispatcher go through the safe HTTP helpers in
  `packages/engine/src/utils/safe-http.ts`.

## Data and configuration

- Validate process configuration in `packages/engine/src/config.ts`; do not scatter direct
  `process.env` reads. Existing documented test seams and subprocess filters are exceptions.
- Tenant- or instance-specific values are rows with a process default, not deployment-only
  environment variables.
- Instance slugs and UUIDs are distinct branded identifiers. Convert only through the
  instance resolver functions; do not guess from a string.
- Tenant predicates fail closed. A missing organization/workspace identifier must never
  remove a query filter and expose all rows.
- Migrations and `packages/engine/src/database/migrations/meta/_journal.json` are updated
  together. Follow the next existing migration number and verify both directions.
- The root `.env` serves the engine and Docker Compose. Next.js local auth configuration
  belongs under `packages/web/.env.local`.
- Never commit secrets or log credentials, tokens, message bodies, or other PII at normal
  production log levels. Keep access metadata and stable IDs separate from payload data.

## TypeScript and package boundaries

- The engine is Node ESM: relative value imports end in `.js`.
- The web app is bundled by Next.js: relative imports under `packages/web/src` are
  extensionless. Custom ESLint rules enforce both directions.
- NestJS constructor dependencies require explicit `@Inject(...)`; the engine ESLint rule
  enforces this because `tsx` does not emit decorator metadata.
- Follow existing identifier, schema, export, and file-name patterns in the touched module.
  Do not impose a repository-wide rule contradicted by nearby code.
- Never edit generated or vendored files by hand. Regenerate them using the owning script.

## Scoped guidance

Claude Code loads these rules when matching files are read. Other agents should open the
same file before changing that scope:

- Engine TypeScript: `.claude/rules/engine.md`
- Web TypeScript/React: `.claude/rules/web.md`
- Tests: `.claude/rules/tests.md`
- Database migrations: `.claude/rules/migrations.md`

Skills are task procedures, not an extra source of product truth. They must be safe to run
twice, inspect current state before mutation, and use repository scripts instead of assuming
a particular agent or shell alias.

## Git and releases

- Work on a topic branch from the intended base. `develop` is integration; `main` carries
  releases. Never push directly to either protected branch.
- Use focused conventional commits in English and add the DCO sign-off with `git commit -s`.
- Check the current branch and staged diff immediately before every commit.
- Before any release preparation, promotion, tag, or publication, load
  `.claude/skills/release/SKILL.md`. Release publication always requires an explicit final
  confirmation of the version and immutable target SHA.