Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 95 additions & 25 deletions AGENTS.MD
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,126 @@ Welcome to the Etherpad project. This guide provides essential context and instr
Etherpad is a real-time collaborative editor designed to be lightweight, scalable, and highly extensible via plugins.

## Technical Stack
- **Runtime:** Node.js
- **Package Manager:** pnpm
- **Languages:** TypeScript (primary), JavaScript, CSS, HTML
- **Backend:** Express.js, Socket.io
- **Frontend:** Legacy core (`src/static`), New UI (`ui/`), Admin UI (`admin/`)
- **Build Tools:** Vite (for `ui` and `admin`), custom scripts in `bin/`
- **Testing:** Mocha (Backend), Vitest, Playwright, custom backend test suite
- **Runtime:** Node.js >= 20.0.0
- **Package Manager:** pnpm (>= 8.3.0)
- **Languages:** TypeScript (primary for new code), JavaScript (legacy), CSS, HTML
- **Backend:** Express.js 5, Socket.io 4
- **Frontend:** Legacy core (`src/static`), Modern React UI (`ui/`), Admin UI (`admin/`)
- **Database:** ueberdb2 abstraction (supports dirtyDB, MySQL, PostgreSQL, Redis)
- **Build Tools:** Vite (for `ui` and `admin`), esbuild, tsx
- **Testing:** Mocha (backend), Playwright (frontend E2E), Vitest (unit)
- **Auth:** JWT (jose library), OIDC provider

## Directory Structure
- `src/node/`: Backend logic, API, and database abstraction.
- `src/static/`: Core frontend logic (Legacy).
- `ui/`: Modern React-based user interface.
- `admin/`: Modern React-based administration interface.
- `bin/`: Utility and lifecycle scripts.
- `doc/`: Documentation in Markdown and Adoc formats.
- `src/tests/`: Test suites (backend, frontend, UI, admin).
- `var/`: Runtime data (logs, dirtyDB, etc. - ignored by git).
- `local_plugins/`: Directory for developing and testing plugins locally.
- `src/node/` - Backend logic, API handlers, database models, hooks
- `src/static/` - Core frontend logic (legacy jQuery-based editor)
- `src/static/js/pluginfw/` - Plugin framework (installer, hook system)
- `src/tests/` - Test suites (backend, frontend, container)
- `ui/` - Modern React OIDC login UI (Vite + TypeScript)
- `admin/` - Modern React admin panel (Vite + TypeScript + Radix UI)
- `bin/` - CLI utilities, build scripts, plugin management tools
- `bin/plugins/` - Plugin maintenance scripts (checkPlugin.ts, updateCorePlugins.sh)
- `doc/` - Documentation (VitePress + Markdown/AsciiDoc)
- `local_plugins/` - Directory for developing and testing plugins locally
- `var/` - Runtime data (logs, dirtyDB, etc. - ignored by git)

## Quick Start

```bash
pnpm install # Install all dependencies
pnpm run build:etherpad # Build admin UI and static assets
pnpm --filter ep_etherpad-lite run dev # Start dev server (port 9001)
pnpm --filter ep_etherpad-lite run prod # Start production server
```

## Core Mandates & Conventions

### Coding Style
- **Indentation:** 2 spaces for all files (JS/TS/CSS/HTML).
- **No Tabs:** Use spaces only.
- **Comments:** Provide clear comments for complex logic.
- **Indentation:** 2 spaces for all files (JS/TS/CSS/HTML). No tabs.
- **TypeScript:** All new code should be TypeScript. Strict mode is enabled.
- **Comments:** Provide clear comments for complex logic only.
- **Backward Compatibility:** Always ensure compatibility with older versions of the database and configuration files.

### Development Workflow
- **Branching:** Work in feature branches. Issue PRs against the `develop` branch.
- **Branching:** Work in feature branches. Issue PRs against the `develop` branch. Never PR directly to `master`.
- **Commits:** Maintain a linear history (no merge commits). Use meaningful messages in the format: `submodule: description`.
- **Feature Flags:** New features should be placed behind feature flags and disabled by default.
- **Deprecation:** Never remove features abruptly; deprecate them first with a `WARN` log.
- **Forks:** For etherpad-lite changes, commit to `johnmclear/etherpad-lite` fork on a new branch, then PR to `ether/etherpad-lite`. For plugins (`ep_*` repos), committing directly is acceptable.

### Testing & Validation
- **Requirement:** Every bug fix MUST include a regression test in the same commit.
- **Backend Tests:** Run `pnpm --filter ep_etherpad-lite run test` from the root.
- **Frontend Tests:** Accessible at `/tests/frontend` on a running instance.
- **Linting:** Run `pnpm run lint` to ensure style compliance.
- **Build:** Run `pnpm run build:etherpad` before production deployment.
- **Backend Tests:** `pnpm --filter ep_etherpad-lite run test`
- **Frontend E2E Tests:** `pnpm --filter ep_etherpad-lite run test-ui`
- **Admin Tests:** `pnpm --filter ep_etherpad-lite run test-admin`
- **Linting:** `pnpm run lint`
- **Type Check:** `pnpm --filter ep_etherpad-lite run ts-check`
- **Build:** `pnpm run build:etherpad` before production deployment

### Backend Test Auth
Tests use JWT authentication, not API keys. Pattern:
```typescript
import * as common from 'ep_etherpad-lite/tests/backend/common';

const agent = await common.init(); // Starts server, returns supertest agent
const token = await common.generateJWTToken();
agent.get('/api/1/endpoint').set('authorization', token);
```
Do not use `APIKEY.txt` — it may not exist in the test environment.

## Key Concepts

### Easysync
The real-time synchronization engine. It is complex; refer to `doc/public/easysync/` before modifying core synchronization logic.

### Plugin Framework
Most functionality should be implemented as plugins (`ep_...`). Avoid modifying the core unless absolutely necessary.
Most functionality should be implemented as plugins (`ep_*`). Avoid modifying the core unless absolutely necessary.

**Plugin structure:**
```
ep_myplugin/
├── ep.json # Hook declarations (server_hooks, client_hooks)
├── index.js # Server-side hook implementations
├── package.json
├── static/
│ ├── js/ # Client-side code
│ ├── css/
│ └── tests/
│ ├── backend/specs/ # Backend tests (Mocha)
│ └── frontend-new/ # Frontend tests (Playwright)
├── templates/ # EJS templates
└── locales/ # i18n files
```

**Plugin management:**
```bash
pnpm run plugins i ep_plugin_name # Install from npm
pnpm run plugins i --path ../plugin # Install from local path
pnpm run plugins rm ep_plugin_name # Remove
pnpm run plugins ls # List installed
```

**Plugin installation internals:** Plugins are installed to `src/plugin_packages/` via `live-plugin-manager`, which stores them at `src/plugin_packages/.versions/ep_name@version/`. Symlinks are created: `src/node_modules/ep_name` → `src/plugin_packages/ep_name` → `.versions/ep_name@ver/`.

### Plugin Repositories
- **Monorepo:** `ether/ether-plugins` contains 80+ plugins with shared CI/publishing
- **Standalone repos:** Individual `ether/ep_*` repos still exist for many plugins
- **Plugin CI templates:** `bin/plugins/lib/` contains workflow templates pushed to standalone plugin repos via `checkPlugin.ts`
- **Shared pipelines:** `ether/ether-pipelines` contains reusable GitHub Actions workflows for plugin CI

### Settings
Configured via `settings.json`. A template is available at `settings.json.template`. Environment variables can override any setting using `"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`.

## Monorepo Structure

This project uses pnpm workspaces. The workspaces are:
- `src/` - Core Etherpad (package: `ep_etherpad-lite`)
- `bin/` - CLI tools and plugin scripts
- `ui/` - Login UI
- `admin/` - Admin panel
- `doc/` - Documentation

Root-level commands operate across all workspaces. Use `pnpm --filter <package>` to target specific workspaces.

## AI-Specific Guidance
AI/Agent contributions are explicitly welcomed by the maintainers, provided they strictly adhere to the guidelines in `CONTRIBUTING.md` and this guide. Always prioritize stability, readability, and compatibility.
Loading