# AGENTS.md

This file provides guidance for AI coding agents (Claude Code, Codex, Gemini CLI, etc.) working in this repository.

## Navigation

- Locating files or understanding structure → [Repository Structure](#repository-structure)
- Writing or reviewing PHP → [Key Conventions → PHP](#php) + [Known Constraints → PHP Constraints](#php-constraints)
- Working on REST API controllers → [Key Conventions → REST API](#rest-api)
- Editing styles or scripts → [Key Conventions → CSS/JS](#cssjs) + [Known Constraints → JavaScript](#javascript)
- Checks required before committing → [Development Workflow](#development-workflow)
- Branch naming or commit format → [Creating Branches](#creating-branches) + [Commits](#commits)
- Verifying whether a file is safe to modify → [What Not to Touch](#what-not-to-touch)

## Project Overview

**CoCart Community** is an open-source, developer-first REST API plugin for WooCommerce. It exposes product browsing, cart management, and session handling as a WordPress REST API — purpose-built for headless and decoupled storefronts.

- **Plugin file:** `cart-rest-api-for-woocommerce.php`
- **Main class:** `includes/class-cocart.php` → singleton via `CoCart()`
- **Autoloader:** `includes/class-cocart-autoloader.php` (PSR-4 from `includes/`)
- **Text domain:** `cart-rest-api-for-woocommerce`
- **PHP minimum:** 8.2
- **WordPress minimum:** 6.7
- **WooCommerce minimum:** 9.0
- **Default branch:** `trunk`
- **License:** GPLv3+

## Repository Structure

```text
cart-rest-api-for-woocommerce.php   # Main plugin file — defines constants, boots plugin
load-package.php                    # Package loader
uninstall.php                       # Uninstall cleanup
includes/
├── class-cocart.php                # Main class — hooks, init, load sequence
├── class-cocart-autoloader.php     # PSR-4 autoloader
├── cocart-*.php                    # Standalone function files (formatting, deprecated, etc.)
├── abstracts/                      # Abstract base classes
├── classes/
│   ├── rest-api/                   # REST API controllers, authentication, caching, responses
│   ├── admin/                      # WordPress admin UI, notices, setup wizard, update checks
│   ├── cli/                        # WP-CLI commands
│   └── integrations/               # Third-party plugin compatibility handlers
└── utilities/                      # Shared utility helpers
assets/
├── scss/                           # SCSS source — only this is tracked in git
├── css/                            # Compiled CSS — generated by CI, not tracked
├── js/                             # JS source; *.min.js compiled by CI, not tracked
└── images/                         # Static images
languages/                          # Only README.md tracked; .pot/.po/.mo generated by CI
bin/                                # Release and build shell scripts
```

## Key Conventions

### PHP

- Follow [WordPress Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/)
- Use `cart-rest-api-for-woocommerce` as the text domain in all translatable strings
- Use numbered arguments in `printf`/`sprintf` when replacing more than one value: `%1$s`, `%2$s`
- Use sentence case for translatable strings: `Some thing` not `Some Thing`
- Avoid HTML in strings — insert via `sprintf` instead
- Do not call deprecated functions from plugin source; use replacement functions directly
- Use `COCART_FILE` and `COCART_SLUG` constants — do not hardcode the plugin path or slug

### REST API

- REST API controllers live in `includes/classes/rest-api/`
- CoCart uses WooCommerce Data Stores API for session management — not WooCommerce default sessions
- ETag support, cache headers, and CORS handling are built-in — do not bypass them
- Authentication is via JWT or Basic Auth only — no cookie/nonce auth for API requests

### CSS/JS

- Edit SCSS source in `assets/scss/` — never edit compiled CSS in `assets/css/`
- Compiled CSS and minified JS are generated by CI (`npx grunt css js`) — do not commit them
- RTL CSS is auto-generated from compiled CSS — do not create RTL files manually

## Build Commands

```bash
# Install dependencies
npm ci
composer install

# Compile CSS and JS
npx grunt css js

# Watch for changes during development
npx grunt watch

# Code standards
composer phpcs          # Check PHP coding standards
composer phpcbf         # Auto-fix coding standards issues
composer phpstan        # Static analysis

# Fix text domain references
npm run fix:textdomain
```

## Development Workflow

1. Make code changes
2. Run `composer phpcs` on changed PHP files — fix all violations before continuing
3. Run `composer phpstan` on changed PHP files — fix errors in code, never add to baseline
4. Compile assets if SCSS/JS changed: `npx grunt css js`
5. Commit only after checks are clean
6. Open a pull request against `trunk`

### Pre-commit Checks

**Before committing PHP changes**, run these to avoid CI failures:

```bash
# Check coding standards on changed files
composer phpcs

# Static analysis
composer phpstan
```

**PHPStan baseline policy:** The baseline file (`phpstan-baseline.neon`) must never grow. If PHPStan reports a new error, fix it in the code. If your fix resolves a previously baselined error, remove the corresponding entry from the baseline. The baseline should only shrink over time.

## Known Constraints

### Project Structure

- Never add standalone global functions outside the designated `includes/cocart-*.php` function files
- Never modify `CHANGELOG.md` — updated by the CoCart team only
- Never commit compiled CSS (`assets/css/`) or minified JS (`assets/js/**/*.min.js`) — generated by CI
- Never commit `.pot` files — generated by CI
- Never edit RTL CSS files manually — auto-generated from compiled CSS
- All new classes go in `includes/classes/` under the appropriate subdirectory
- `includes/` legacy function files should only be modified when no class-based alternative exists

### JavaScript

- Never write inline JavaScript — all JS must live in enqueued script files so it can be compiled, linted, and minified
- Never use dynamic code execution functions (`call`, `apply`, `Function` constructor, or similar patterns that execute strings as code)
- Never enqueue scripts or styles outside the designated admin class

### PHP Constraints

- Never use `var_dump()`, `print_r()`, or `error_log()` in committed code — remove all debug output before committing
- Never access `$_GET`, `$_POST`, or `$_SERVER` directly in REST API controllers — use `WP_REST_Request` parameter methods
- Never write raw database queries — use WooCommerce Data Stores or existing CoCart abstractions
- Never use `wp_die()` inside REST API controllers — return a `WP_Error` instance instead
- Never output unescaped content — use `esc_html()`, `esc_attr()`, `wp_json_encode()`, or the appropriate escaping function
- Never hardcode credentials, tokens, or API keys — use WordPress options or constants defined outside the codebase
- Never read options directly where a CoCart settings abstraction already exists — use the abstraction

## What Not to Touch

- **`CHANGELOG.md`** — updated by the CoCart team, not contributors
- **`languages/*.pot`** — generated by CI (`wp i18n make-pot`), not tracked in git
- **`assets/css/`** — compiled by CI, not tracked in git
- **`assets/js/**/*.min.js`** — compiled by CI, not tracked in git
- **`vendor/`** — managed by Composer, not tracked in git
- **`node_modules/`** — managed by npm, not tracked in git
- **`.phpcs.xml.dist`** — do not change coding standard rules without discussion

## Creating Branches

Branch names follow this structure (`{short-slug}` = brief descriptor of the change):

- `release/{version}` — release branches
- `refactor/{short-slug}` — refactors
- `test/{short-slug}` — test-only changes
- `fix/{issue-number}-{short-slug}` — bug fixes (always include the issue number)
- `add/{short-slug}` — new features

## Commits

- Each commit should address one atomic unit of work
- Subject line: imperative mood, no trailing period, max 50 characters (e.g. `Fix session expiry on guest checkout`)
- Blank line between subject and body
- Body lines: max 72 characters
- Explain *what* and *why*, not just *how* — only explain *how* if it isn't obvious
- Reference the related issue number in the commit body (e.g. `Fixes #123`)
- Do not amend published commits

## Agent Rules

- Run pre-commit checks before every commit — do not skip them for any reason
- Do not modify generated files (`assets/css/`, `*.min.js`, `*.pot`) — CI overwrites them
- Do not add entries to the PHPStan baseline — fix the error in code instead
- Do not create new files when an existing class can be extended or modified
- Do not reach past a CoCart abstraction to call WordPress or WooCommerce directly — use the abstraction
- Do not amend commits that have already been pushed
- Check [What Not to Touch](#what-not-to-touch) before modifying any file you are uncertain about
- Check [Known Constraints](#known-constraints) before writing any new PHP, JS, or SQL
