CONTRIBUTING.md
Rama main · réplica de lectura del repositorio original.
# Contributing to Ant
Thanks for your interest in Ant. This document describes how to set up the
project locally, the conventions we follow, and how to send a pull request
that has the best chance of getting merged quickly.
If you only have a few minutes, please read **[Quick checklist](#quick-checklist)**.
This project and everyone participating in it is governed by our
[Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to
uphold it.
---
## Project Layout
```
packages/
├── ant-cli/ Backend: API / Job worker / Realtime / Preview
├── ant-ui/ Frontend: React + Vite SPA
├── ant-site/ Marketing site (Next.js, static export) — not part of the runtime
├── ant-auth-client/ Shared browser auth helpers (ant-ui + ant-site)
└── ant-shared/ Types + shared runtime used by every package
docs/
├── local-mode/ install + develop on your own machine
├── cloud-mode/ install + develop for managed or self-host cloud
├── getting-started/ first-feature walkthrough, troubleshooting
├── concepts/ architecture, agents, jobs, execution tiers
├── guides/ design input, custom prompts, observability
├── reference/ CLI, env vars, API, shared types
└── internals/ contributor-only deep-dives (SSOT, debug logging)
```
`ant-shared` exports both types and runtime code (canonical paths, the
action-config matrix, pricing, tier matrices). Consumers resolve `types` to
`src/` directly through pnpm workspace resolution, so type changes need no
build — but **runtime** changes do: run
`pnpm --filter @ant/shared build` after editing them.
## Prerequisites
- **Node.js** >= 22.13 (enforced by the root `engines` field)
- **pnpm** 11.1.0 — pinned via `packageManager`
(`corepack enable && corepack prepare pnpm@11.1.0 --activate`)
- **Docker** + Docker Compose — Redis is required; ChromaDB and the
visual-processor are optional sidecars
- **Git** 2.40+
- An LLM provider API key — Anthropic Claude is the primary supported model.
Five other providers are wired; see the [README](README.md#providers).
## Local Setup
- **Install** — [docs/local-mode/install.md](docs/local-mode/install.md)
- **Develop conventions** — [docs/develop.md](docs/develop.md)
Open http://localhost:4200 after `pnpm dev:all`.
## Daily Loop
| Task | Command |
|-------------------------------|-----------------------------------------------|
| Run all tests (CLI) | `pnpm test:cli` |
| Run all tests (UI) | `pnpm --filter @ant/ui test` |
| Run a single test file | `cd packages/ant-cli && pnpm vitest run tests/<path>` |
| Type-check everything | `pnpm typecheck` |
| Type-check the test suite | `pnpm typecheck:tests` |
| Build the project | `pnpm build` |
| Tear down infra | `pnpm dev:infra:down` |
**`pnpm build` does not run tests, and no `prebuild` hook should be added** —
the Dockerfile builds with `pnpm build:cli`, and charging every image build the
full suite is a deliberate non-goal. **CI is the only gate**
([.github/workflows/ci.yml](.github/workflows/ci.yml)): `typecheck:cli`,
`typecheck:ui`, `typecheck:tests`, `test:cli`, `@ant/ui test`, plus the
`oss-guard` and `boot-smoke` jobs. Run those four commands locally before you
push.
## Coding Conventions
### TypeScript
- **Strict mode** is on. Do not turn it off in PRs.
- Prefer **explicit types** at module boundaries (exported functions, public
classes). Local inference is fine.
- Use `unknown` over `any`. If you need `any`, justify it in a code comment.
- Keep modules small and cohesive — one concept per file.
### Code Style
- ESLint + Prettier are authoritative. `pnpm lint` (when configured per
package) and editor format-on-save handle the basics.
- Console logs use **emoji prefixes** for grep-ability:
`📄 [DocGen]`, `🔧 [Tool]`, `🚀 [JobWorker]`, etc. Keep them consistent
with the surrounding module.
- Comments are lean. Don't translate code line-by-line. Add comments only for
non-obvious invariants, external contracts, or tricky trade-offs (one
sentence is usually enough). See [AGENTS.md](AGENTS.md) "Comments — lean by
default" for the full rationale.
- JSDoc only for public APIs and `@deprecated` markers. Don't JSDoc every
function.
### Architecture Rules
Ant has a small set of binding architectural rules that protect the core
contract. The full SSOT lives in [AGENTS.md](AGENTS.md), but the most common
ones to remember:
- **Distributed-system principle**: no in-memory fallbacks for Redis / BullMQ.
If it doesn't work without Redis, fix it; don't add a Map.
- **Phase nodes are task-type blind**: never write
`if (task.type === 'verification')` inside `nodes/`, `routers/`, or
`parallel/` — task-specific logic lives in `tasks/{type}/hooks/`.
- **PromptBuilder is the only entry point for prompts.** Do not call
Handlebars or `render()` directly to bypass system layers.
- **state.artifacts is RAC-bound.** Only `loadResolvedArtifacts` and
`appendOrUpdatePool` may write to the artifact pool.
When in doubt, read [AGENTS.md](AGENTS.md). It is the canonical reference and
includes regression-guard test names for every rule.
### Tests
- Test files live next to the package they cover, e.g.
`packages/ant-cli/tests/<area>/*.test.ts`.
- Use **Vitest**. Prefer behaviour-level tests over implementation tests.
- New invariants in core agent / orchestrator code should ship with a test
that fails when the invariant is violated.
- Snapshot tests are allowed but should be small and reviewed.
### Prompt Templates
If you touch any file under
`packages/ant-cli/src/core/prompt/templates/`, read the **Prompt Engineering**
section in [AGENTS.md](AGENTS.md) first. Prompts are part of the public API
the agents stand on; small drifts produce hard-to-debug regressions.
Key disciplines:
- **FPOP**: principles over examples, what over how, observable over assumed.
- **SBS**: gated templates must be specific along the gate axis; always-on
templates must stay universal.
- **Language**: prompt templates are **English only**. Comments in source
files may be Korean if helpful, but no Korean lands in `.md` templates.
## Pull Requests
### Quick Checklist
Before opening a PR, please confirm:
- [ ] `pnpm typecheck` and `pnpm typecheck:tests` are clean
- [ ] `pnpm test:cli` and `pnpm --filter @ant/ui test` pass
- [ ] You added or updated tests when changing behaviour
- [ ] No incident codenames or internal hostnames in code, comments, or docs
- [ ] If you touched prompts, you ran the relevant prompt-policy tests (see
[AGENTS.md](AGENTS.md) "Enforcement" blocks)
- [ ] PR description follows the template (`.github/PULL_REQUEST_TEMPLATE.md`)
### Sizing
Keep PRs small. A good target:
- **< 400 changed lines** of production code.
- One concern per PR (refactor + feature in separate PRs).
- Tests in the same PR as the behaviour they cover.
If a refactor is large, split it into a stack of PRs and describe the order in
the first PR's description.
### Commit Messages
We use **Conventional Commits**:
```
<type>(<scope>): <short summary>
<body — optional, wrap at 72 cols>
```
Common types: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`.
Examples (from real commits):
```
feat(preview): Phase 1 service virtualization — ConnectionDetector + @connection grammar
fix(decompose): retry on JsonSyntaxViolation in LLM task JSON parse
refactor(preview): drop mock:* annotation tokens
```
### Review Process
- One maintainer approval is required to merge.
- We use **squash merge** by default — your branch's commit history will be
squashed into one commit on `main`.
- CI must be green. Don't `[skip ci]` to bypass.
- Ant is maintained by one person, so reviews are best-effort. If a PR has had
no response after a week, bump it with a comment — that is not rude, it is
helpful.
## Dependency Updates
Dependabot owns the routine lane, configured in
[`.github/dependabot.yml`](.github/dependabot.yml). Three weekly npm groups —
`volatile` (0.x SDKs and generated-export packages, where a semver-minor can
still be breaking), `prod-minor-patch`, and `dev-minor-patch` — plus one
`actions` group. Patch bumps and dev-dependency minors auto-merge on green CI
via [`dependabot-automerge.yml`](.github/workflows/dependabot-automerge.yml);
everything else needs a human.
**Majors are not proposed.** `dependabot.yml` ignores
`version-update:semver-major` for npm, because a major that needs a source
migration (tailwindcss 3 → 4, archiver 7 → 8) otherwise sits red forever and
eats the open-PR limit until Dependabot stops opening PRs at all. They are
picked up deliberately instead, once a quarter:
1. `pnpm outdated -r` for the major gap.
2. Per entry: migrate / defer / drop the dependency (some are simply unused —
`http-proxy-middleware` was carried for two majors while the code used
`http-proxy` directly).
3. File an issue for anything deferred so the next sweep sees it.
**When you hand-bump a manifest for a CVE**, check whether an open Dependabot
PR already covers that package. If it does, comment `@dependabot rebase` on it
instead of landing a separate commit — two channels pushing the same manifest is
how PRs go stale, re-run CI, and drift from their base.
## Reporting Bugs
- For **security** issues, see [SECURITY.md](SECURITY.md). Please do not file
public issues for vulnerabilities.
- For **functional** bugs, open an issue using the bug-report template
(`.github/ISSUE_TEMPLATE/bug_report.yml`). Include reproduction steps, the
command you ran, and the relevant logs (redact API keys).
## Proposing Features
- Open an issue using the feature-request template before writing a large
patch. We want to align on direction first.
- For changes that affect cross-package contracts (`@ant/shared` types, SSE
events, Redis keys), include a short design note in the issue.
## License
By contributing you agree that your contributions are licensed under the
[Apache License 2.0](LICENSE), the same license that covers the project. This
is the default Apache-2.0 §5 behaviour — there is **no CLA to sign and no DCO
sign-off required**.
If you add a dependency whose license is not MIT / ISC / Apache-2.0 / BSD, note
it in [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) in the same PR.
## Getting Help
- **Documentation**: start with `docs/local-mode/install.md` and `docs/concepts/`.
- **Discussions**: for open-ended questions, use
[GitHub Discussions](https://github.com/to-nexus/ant/discussions). There is no Discord or other chat
channel — a one-person project cannot staff one, and a dead server is worse
than none.
Thanks again for contributing.