This file provides guidance to AI coding assistants working with code in this repository.
composer i
npm ciSee package.json scripts for all available commands (build, dev, watch, lint, stylelint, test:unit, test:e2e, etc.).
See composer.json scripts for all available commands (cs:check, cs:fix, psalm, test:unit, test:integration, openapi, etc.).
- Backend: PHP (see
appinfo/info.xmlfor version requirements), Nextcloud app framework, Horde IMAP/MIME/SMTP libraries. Namespace:OCA\Mail\. - Frontend: Vue 2, Pinia, Vue Router 3, CKEditor 5, bundled with webpack.
Layered: Controllers β Services β DB Mappers.
Controller/β Thin HTTP handlers; business logic lives in services.Service/β Core logic. Key areas: account management, IMAP sync, mail sending (SMTP), drafts/outbox, S/MIME encryption, ML-based importance classification, AI integrations (thread summaries, follow-up detection).Db/β NextcloudQBMapper-based mappers and entity models.IMAP/β Low-level IMAP via Horde.IMAPClientFactorycreates authenticated clients;MessageMapperfetches raw messages.BackgroundJob/β Nextcloud background jobs for IMAP sync, ML training, outbox sending, etc.Listener/β Event listeners hooked to domain events fromlib/Events/.Contracts/β Interfaces defining main service boundaries (IMailManager,IMailTransmission, etc.).Migration/β Database migrations.
Single-page Vue 2 app. All routes render through views/Home.vue.
store/mainStore.jsβ Central Pinia store (accounts, mailboxes, messages, preferences), split intoactions.jsandgetters.js. Separate stores for outbox and mail filters.service/β JS services that call the PHP REST API.components/β Vue components (composer, envelope list, thread view, settings, etc.).router.jsβ Routes for mailbox, thread, outbox, and setup views.
- Registration:
appinfo/info.xmlregisters background jobs, CLI commands, settings pages, navigation entries, and repair steps.AppInfo/Application.phpregisters event listeners and other services via the Nextcloud bootstrap API. - Events: Domain events in
lib/Events/are dispatched after state changes;lib/Listener/reacts to them. - Mozart: Some vendor packages are namespaced into
lib/Vendor/to avoid conflicts. - REUSE: Every file requires an SPDX license header (
AGPL-3.0-or-laterfor new files). - OpenAPI:
ResponseDefinitions.phpdocuments API types; runcomposer openapito regenerate the spec.
Located in tests/Unit/ with structure mirroring lib/.
- Use arrange-act-assert structure with blank lines separating each phase (no literal comments)
- Mock dependencies via
$this->createMock(Interface::class) - Setup mocks in
setUp()for common fixtures
composer test:unit # Run all unit tests
composer test:unit -- tests/Unit/Service/HtmlTest.php # Run specific test file
composer test:unit -- --filter="TestClassName" # Run tests matching filterDo NOT commit changes unless explicitly asked to do so.
After completing code changes:
- Verify your work is complete and tests pass
- Make sure there is no trailing whitespace
- Leave changes in working directory or staged (do not commit)
- Provide a summary of what was changed and why
- Suggest a commit message using Conventional Commits format
- There is a contributing doc with suggestions
- The user will review and commit when ready
The commit message's last line before sign-off should be AI-assisted: <agent> (model). For example: AI-assisted: Claude Code (Claude Haiku 4.5)