{"owner":"vxcontrol","repo":"pentagi","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["CLAUDE.md"],"files":{"CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## Core Interaction Rules\n\n1. **Always use English** for all interactions, responses, explanations, and questions with users.\n2. **Password Complexity Requirements**: For all password-related development (registration, password reset, API token generation, etc.), enforce the same policy in **both** backend and frontend — never rely on frontend validation alone. Source of truth, keep the two in sync: `backend/pkg/server/models/init.go` → `strongPasswordValidatorString` and `frontend/src/features/authentication/password-change-form.tsx` (zod schema). The policy:\n   - Length 8–72 characters (72 **bytes**, the most bcrypt will hash — a longer value fails inside `bcrypt.GenerateFromPassword`, after validation).\n   - A password is valid if it is **either** 16+ characters (any composition), **or** 8–15 characters containing at least 1 lowercase letter, 1 uppercase letter, 1 number, and 1 special character from `!@#$&*`.\n\n## Project Overview\n\n**PentAGI** is an automated security testing platform powered by AI agents. It runs autonomous penetration testing workflows using a multi-agent system (Researcher, Developer, Executor agents) that coordinates LLM providers, Docker-sandboxed tool execution, and a persistent vector memory store.\n\nThe application is a monorepo with:\n- **`backend/`** — Go REST + GraphQL API server\n- **`frontend/`** — React + TypeScript web UI\n- **`observability/`** — Optional monitoring stack configs\n\n## Build & Development Commands\n\n### Backend (run from `backend/`)\n\n```bash\ngo mod download                              # Install dependencies\ngo build -trimpath -o pentagi ./cmd/pentagi  # Build main binary\ngo test ./...                                # Run all tests\ngo test ./pkg/foo/... -v -run TestName       # Run specific test\ngolangci-lint run --timeout=5m               # Lint\n\n# Code generation (run after schema changes)\ngo run github.com/99designs/gqlgen --config ./gqlgen/gqlgen.yml  # GraphQL resolvers\nswag init -g ../../pkg/server/router.go -o pkg/server/docs/ --parseDependency --parseInternal --parseDepth 2 -d cmd/pentagi  # Swagger docs\n```\n\n### Frontend (run from `frontend/`)\n\n```bash\npnpm install              # Install dependencies\npnpm run dev              # Dev server on http://localhost:8000\npnpm run build            # Production build\npnpm run lint             # ESLint check\npnpm run lint:fix         # ESLint auto-fix\npnpm run prettier         # Prettier check\npnpm run prettier:fix     # Prettier auto-format\npnpm run test             # Vitest\npnpm run test:coverage    # Coverage report\npnpm run graphql:generate # Regenerate GraphQL types from schema\n```\n\n### Docker (run from repo root)\n\n```bash\ndocker compose up -d                                                          # Start core services\ndocker compose -f docker-compose.yml -f docker-compose-observability.yml up -d  # + monitoring\ndocker compose -f docker-compose.yml -f docker-compose-langfuse.yml up -d       # + LLM analytics\ndocker compose -f docker-compose.yml -f docker-compose-graphiti.yml up -d       # + knowledge graph\ndocker build -t local/pentagi:latest .                                        # Build image\n```\n\nThe full stack runs at `https://localhost:8443` when using Docker Compose. Copy `.env.example` to `.env` and fill in at minimum the database and at least one LLM provider key.\n\n## Architecture\n\n### Backend Package Structure\n\n| Package | Role |\n|---|---|\n| `cmd/pentagi/` | Main entry point; initializes config, DB, server |\n| `pkg/config/` | Environment-based config parsing |\n| `pkg/server/` | Gin router, middleware, auth (JWT/OAuth2/API tokens), Swagger |\n| `pkg/controller/` | Business logic for REST endpoints |\n| `pkg/graph/` | gqlgen GraphQL schema (`schema.graphqls`) and resolvers |\n| `pkg/database/` | GORM models, SQLC queries, goose migrations |\n| `pkg/providers/` | LLM provider adapters (OpenAI, Anthropic, Gemini, Bedrock, Ollama, etc.) |\n| `pkg/tools/` | Penetration testing tool integrations |\n| `pkg/docker/` | Docker SDK wrapper for sandboxed container execution |\n| `pkg/terminal/` | Terminal session and command execution management |\n| `pkg/csum/` | Chain summarization for LLM context management |\n| `pkg/graphiti/` | Knowledge graph (Neo4j via Graphiti) integration |\n| `pkg/observability/` | OpenTelemetry tracing, metrics, structured logging |\n\nDatabase migrations live in `backend/migrations/sql/` and run automatically via goose at startup.\n\n### Frontend Structure\n\n```\nfrontend/src/\n├── app.tsx / main.tsx     # Entry points and router setup\n├── pages/                 # Route-level page components\n│   ├── flows/             # Flow management UI\n│   └── settings/          # Provider, prompt, token settings\n├── components/\n│   ├── layouts/           # App shell layouts\n│   └── ui/                # Base Radix UI components\n├── graphql/               # Auto-generated Apollo types (do not edit)\n├── hooks/                 # Custom React hooks\n├── lib/                   # Apollo client, HTTP utilities\n└── schemas/               # Zod validation schemas\n```\n\nState is managed primarily through Apollo Client (GraphQL) with real-time updates via GraphQL subscriptions over WebSocket.\n\n### Data Flow\n\n1. User creates a \"flow\" (penetration test) via the UI or REST API.\n2. The backend queues the flow and spawns agent goroutines.\n3. The Researcher agent gathers information; the Developer plans attack strategies; the Executor runs tools in isolated Docker containers.\n4. Results, tool outputs, and LLM reasoning are stored in PostgreSQL (with pgvector for semantic search/memory).\n5. Real-time progress is pushed to the frontend via GraphQL subscriptions.\n\n### Authentication\n\n- **Session cookies** for browser login (secure, httpOnly)\n- **OAuth2** via Google and GitHub\n- **Bearer tokens** (API tokens table) for programmatic API access\n\n### Key Integrations\n\n- **LLM Providers**: OpenAI, Anthropic, Gemini, AWS Bedrock, Ollama, DeepSeek, GLM, Kimi, Qwen, and custom HTTP endpoints — configured via environment variables or the Settings UI\n- **Search**: DuckDuckGo, Google, Tavily, Firecrawl, Traversaal, Perplexity, Searxng\n- **Databases**: PostgreSQL + pgvector (required), Neo4j (optional, for knowledge graph)\n- **Observability**: OpenTelemetry → VictoriaMetrics + Loki + Jaeger → Grafana; Langfuse for LLM analytics\n\n### Adding a New LLM Provider\n\n1. Create `backend/pkg/providers/<name>/<name>.go` implementing the `provider.Provider` interface.\n2. Add a new `Provider<Name> ProviderType` constant and `DefaultProviderName<Name>` in `pkg/providers/provider/provider.go`.\n3. Register the provider in `pkg/providers/providers.go` (`DefaultProviderConfig`, `NewProvider`, `buildProviderFromConfig`, `GetProvider`).\n4. Add the new type to the `Valid()` whitelist in `pkg/server/models/providers.go` — **without this step, the REST API returns 422 Unprocessable Entity**.\n5. Add the env var key to `pkg/config/config.go` (e.g., `<NAME>_API_KEY`, `<NAME>_SERVER_URL`).\n6. Add the new `PROVIDER_TYPE` enum value via a goose migration in `backend/migrations/sql/`.\n7. Add the provider icon in `frontend/src/components/icons/<name>.tsx` and register it in `frontend/src/components/icons/provider-icon.tsx`.\n8. Update the GraphQL schema/types and frontend settings page if needed.\n\n### Adding a New Search Engine\n\nSearch engines are primitives under `backend/pkg/tools/searchers/`, orchestrated by the single `web_search` tool (`backend/pkg/tools/web_search.go`). Agents never call an engine directly — they call `web_search` with an intent `mode`.\n\n1. Create `backend/pkg/tools/searchers/<name>.go` implementing the `searchers.Searcher` interface: `New<Name>(cfg, …)` constructor, `IsAvailable()`, `Engine()`, and a `Handle(ctx, Request)` that returns **typed** errors (`searchers.Retryable` / `searchers.Fatal` / `searchers.ErrNotConfigured`, or `searchers.ClassifyHTTPStatus`). Never swallow an error into a result string. `searchers` must not import `pkg/tools`.\n2. Add the engine's config field(s) to `pkg/config/config.go`, plus `.env.example`, `docker-compose.yml`, and `config_test.go` defaults.\n3. Construct the engine in `buildSearchEngines` and place its id in the relevant `fallbackStrategy` chains in `web_search.go` — that table is the only place engine priority per mode lives.\n4. Attribution: if the engine needs a **new** `SearchengineType` value (not one that already exists), add a goose migration in `backend/migrations/sql/`, a `SearchengineType<Name>` constant in `pkg/database/models.go`, and reconcile `pkg/server/models/searchlogs.go`. Reusing an existing value needs no migration.\n5. Add `<name>_test.go` in `searchers/` (the shared MITM proxy harness is in `proxy_test.go`); add orchestrator coverage in `web_search_test.go` if behavior changes.\n6. No frontend change is needed: the frontend treats `SearchLog.engine` as an opaque string and displays whatever the orchestrator logs.\n\n### Code Generation\n\nWhen modifying `backend/pkg/graph/schema.graphqls`, re-run the gqlgen command to regenerate resolver stubs. When modifying REST handler annotations, re-run swag to update Swagger docs. When modifying `frontend/src/graphql/*.graphql` query files, re-run `pnpm run graphql:generate` to update TypeScript types.\n\n### Utility Binaries\n\nThe backend contains helper binaries for development/testing:\n- `cmd/ctester/` — tests container execution\n- `cmd/ftester/` — tests LLM function/tool calling\n- `cmd/etester/` — tests embedding providers\n- `cmd/installer/` — interactive TUI wizard for guided deployment setup (configures `.env`, Docker Compose, DB, search engines, etc.)\n"}}