WordPress plugin providing the server-side foundation for WCPOS. This repository keeps project-specific agent context tracked in git so fresh clones are self-contained.
CLAUDE.mdis the top-level project overview for Claude and Codex.AGENTS.mdis the Codex entrypoint and points back to tracked repo context..ai/rules/*.mdccontains project-specific rules that must ship with the repo..claude/skills/*/SKILL.mdcontains project-specific skills that must ship with the repo.- Global maintainer files under
/Users/kilbot/.claudeare optional personal preferences only; do not rely on them for project rules, and do not move project-specific context there. - Do not create duplicate
.codexrule/skill sets when the same project guidance already exists in this repo.
- Use WCPOS in user-facing copy, code comments, and documentation.
- Do not write “WooCommerce POS” except for immutable technical identifiers such as:
- GitHub repo names:
woocommerce-pos,woocommerce-pos-pro - WordPress.org slug:
woocommerce-pos - ZIP filenames and existing metadata keys
- GitHub repo names:
The WCPOS wiki lives in wcpos/wiki and changes daily. It is intentionally NOT vendored into this repo (a pinned submodule went stale and misled agents) — always fetch pages fresh, on demand.
Checkouts that predate the submodule removal may still have a leftover .wiki/ directory (Git cannot delete an initialized submodule's working tree on checkout). Delete it — rm -rf .wiki — and never read from it.
-
Local agents (on Paul's machine): read from the sibling clone at
/Users/kilbot/Projects/wiki, but pull first — the clone can be stale:git -C /Users/kilbot/Projects/wiki pull --ff-only
-
Cloud/CI agents (no sibling clone): fetch specific pages as readable Markdown with the GitHub CLI:
wiki_page=product/overview.md gh api -H 'Accept: application/vnd.github.raw+json' \ "repos/wcpos/wiki/contents/${wiki_page}"
Start with INDEX.md at the wiki root — one line per page — then fetch only the pages you need. Paths below are relative to the wiki repo root.
Relevant pages:
product/overview.md— product and business contextarchitecture/plugin-free.md— free plugin architectureproduct/features.md— feature inventorysupport/index.md— support knowledge
- Follow WordPress and WooCommerce coding conventions configured in
.phpcs.xml.dist. - Use
WCPOS\WooCommercePOS\Loggerinstead oferror_log()in production code. - Preserve backward compatibility when changing public methods; add optional parameters with defaults.
- Minimize admin hook footprint. Register admin handlers only where needed. Remember
admin_post_{action}runs onadmin-post.php, not the originating screen. - Sanitize and validate all request data. Check request origin/context before reading
$_REQUEST. - Scale defensive engineering to the area's risk tier — see
.ai/rules/stakes-tiers.mdc. Read-only or trivially reversible admin settings are Low. Settings endpoints that feed the WCPOS client are Medium unless they control a High operation. Settings screens and endpoints inherit the tier of the operation they control, so writes affecting capabilities, payments, stock, auth, or other non-trivially reversible data are High. Do not escalate past an area's declared tier without asking.
- WCPOS REST routes (
/wcpos/v1/) require theX-WCPOS: 1header. - Admin/settings React frontends use WordPress cookie authentication via
@wordpress/api-fetch. - POS/mobile API requests use JWT access/refresh tokens.
- Prefer
Authorization: Bearer <token>headers. Query-parameter tokens are only for controlled local debugging because they can leak through logs and history. - Apache/FastCGI can strip
Authorization; code must check auth headers with! empty()rather thanisset().
PHP and WordPress tests in this repository must run through Docker/wp-env. Do not use local Composer/PHPUnit as a fallback.
Preferred commands:
# Start Docker/wp-env test environment
pnpm exec wp-env start
# Run targeted PHPUnit
pnpm exec wp-env run --env-cwd='wp-content/plugins/woocommerce-pos' tests-cli -- \
vendor/bin/phpunit -c .phpunit.xml.dist <test-file> --filter <test-name>
# Run project PHP unit script when full-suite validation is appropriate
pnpm run test:unit:phpIf wp-env fails because of port conflicts or environment initialization, diagnose and fix Docker/wp-env, try an isolated wp-env config or alternate ports when appropriate, or ask for help. Do not switch to local composer install, local vendor/bin/phpunit, or symlinked vendor directories.
- Bug fixes require a failing test first.
- Use
WCPOS_REST_Unit_Test_Casehelper methods such as$this->wp_rest_get_request()so required WCPOS headers are included. - Apply settings filters before
parent::setUp()because REST routes capture schema duringrest_api_init. - Use Arrange / Act / Assert structure.
- Name tests
test_[feature]_[scenario]_[expected_result]. - Assertion arguments go
( expected, actual )— this is about ARGUMENT ORDER, not about which assertion to call. Prefer the strictest assertion that fits:assertSameoverassertEquals,assertTrue/assertFalseover equality on booleans,assertContains/assertArrayHasKeyover hand-rolled checks. (tests/includes/Sync/usesassertSameroughly four times as often asassertEquals.)
- Use
pnpmfor workspace commands. - For changed packages, run the relevant package test/build/lint scripts when available.
- If package lint is blocked by known tooling/config mismatch, document the exact command and error rather than claiming it passed.
main is the only trunk. 1.10.0 ships from it, and all work branches from and targets it.
Never commit directly to main — branch off it in a worktree and target the PR's base at main.
next is dead and is being deleted. It was the in-development trunk while main carried the 1.9.x stable line, but that split has ended: main is now ahead of next by a wide margin, and most of what remains on next is merge commits pulling main into it. Do not branch from it, do not target it, and do not ask "main or next?" — the answer is main. This note exists because the previous two-trunk wording kept sending agents to a branch that no longer carries the release.