kumwe / app
Kumwe App 2.0
Package info
Type:project
pkg:composer/kumwe/app
Requires
- php: ^8.5
- ext-ctype: *
- ext-fileinfo: *
- ext-filter: *
- ext-intl: *
- ext-json: *
- ext-mbstring: *
- ext-openssl: *
- ext-pdo: *
- ext-redis: *
- ext-sodium: *
- ext-zip: *
- doctrine/dbal: ^4.4
- joomla/archive: ^4.0
- joomla/di: ^4.0
- joomla/event: ^4.0
- joomla/filesystem: ^4.2
- joomla/filter: ^4.0
- joomla/registry: ^4.0
- laminas/laminas-authentication: ^2.19
- laminas/laminas-diactoros: ^3.8
- laminas/laminas-httphandlerrunner: ^2.13
- mcp/sdk: ^0.7.0
- mezzio/mezzio: ^3.28
- mezzio/mezzio-fastroute: ^3.14
- mezzio/mezzio-helpers: ^5.20
- mezzio/mezzio-problem-details: ^1.19
- mezzio/mezzio-twigrenderer: ^2.19
- monolog/monolog: ^3.9
- psr/clock: ^1.0
- psr/log: ^3.0
- ramsey/uuid: ^4.9
- twig/twig: ^3.26
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-strict-rules: ^2.0
- phpunit/phpunit: ^13.3
- squizlabs/php_codesniffer: ^4.0
Suggests
- ext-pdo_mysql: Required when Kumwe uses MariaDB or MySQL.
- ext-pdo_pgsql: Required when Kumwe uses PostgreSQL.
This package is not auto-updated.
Last update: 2026-08-20 14:36:54 UTC
README
Kumwe is a modern CMS, built with disciplined engineering and AI acceleration. It is two platforms behind one set of rules: a content-management system — managed pages, media, nested menus, and governed publishing workflows in a graphical administrator — and a business application platform — a typed business definition and record runtime with policies, approvals, reports, and an isolated client portal. Both halves run through the same application services, so what the browser allows, the REST API, CLI, MCP tools, workers, and scheduler allow, and what one refuses, the others refuse too.
- Content, media, and navigation are managed records with revisions, workflow states, and audit trails.
- Business definitions declare typed entities, relationships, views, actions, and safe formulas; the runtime generates the administrator and portal surfaces, the REST contract, and the CLI/MCP tools.
- The interface is presented in the language a request resolves to, and an operator changes the wording their people read — relabelling "Client" as "Patient" or "Learner" — from a screen, per message and without a deployment.
- Extensions install through a signed pipeline into a compiled, verified runtime — plugins, components, templates, languages, and message catalogues, without rebuilding the application image.
- Automation is durable: database-backed queues, leases, bounded retries, and recurring schedules.
Entry points: AGENTS.md for contributors, the
coding standard, demo profiles,
workers and scheduler, and the full documentation index.
Quick start: the full demonstration
Docker Engine with Compose v2 is the shortest path. The copied environment selects the documentation
site and the Vast Development Method (VDM) business dataset by default, and database:migrate
installs both.
git clone https://github.com/kumwe/app.git
cd cms
cp .env.example .env
docker compose run --rm app composer install --no-interaction --prefer-dist
docker compose run --rm app php bin/kumwe database:migrate
docker compose up -d --wait
curl --fail http://localhost:8080/health/ready
The app container runs as user ${KUMWE_UID:-1000}:${KUMWE_GID:-1000} over the mounted checkout. If
your host user is not UID 1000, export matching identifiers before the first compose command so the
checkout stays writable from inside the container:
export KUMWE_UID="$(id -u)" KUMWE_GID="$(id -g)"
Create the owner account, then complete the demonstration — sign-ins and example extensions — with
one command. Passwords never travel as arguments; they arrive in files only you can read. Paths
passed to the container must be container-visible, which is why the flags below use the /app prefix
(the checkout is mounted there):
install -m 0600 /dev/null .admin-password # Put a password of at least 12 characters in .admin-password. docker compose run --rm app php bin/kumwe user:create-admin \ --email=owner@example.com \ --name="Site owner" \ --password-file=/app/.admin-password docker compose run --rm app php bin/kumwe demo:install \ --admin-email=owner@example.com \ --admin-password-file=/app/.admin-password \ --credentials-file=/app/storage/private/demo-access-credentials.json rm .admin-password
demo:install provisions the VDM demonstration cast — five staff accounts and six portal client
organizations with nine members — and installs the shipped example extensions (announcements,
asset-inspection, audit-listener, and the horizon-theme site theme, which installs as
selectable and is never activated for you). Each new account receives a generated password written
exactly twice: to the command output and to the owner-only credentials file, which lands on the host
at storage/private/demo-access-credentials.json.
Re-running the command is safe: existing accounts and installed examples are confirmed, no password is re-issued, and the credentials file is only created on a run that actually generated a new password — otherwise the command reports that existing sign-ins remain valid and touches nothing.
Sign in at http://localhost:8080/administrator with the owner or a staff account, and at
http://localhost:8080/portal with a portal member. The site content and business records were
already installed by database:migrate; the getting-started guide
continues from here.
Without Docker
The same flow runs on host PHP 8.5 with MariaDB (or MySQL/PostgreSQL) and Redis reachable from the
process. Point DB_HOST and REDIS_HOST in .env at your services (for example 127.0.0.1), then:
composer install cp .env.example .env # edit DB_HOST and REDIS_HOST first php bin/kumwe database:migrate sh tools/development-server.sh # serves http://localhost:8080
Run the same user:create-admin and demo:install commands with host-absolute paths — for example
--admin-password-file="$PWD/.admin-password" and
--credentials-file="$PWD/storage/private/demo-access-credentials.json". The password and
credentials file rules are identical: absolute paths, regular files, no group or other permission
bits. Composer-project and release-ZIP installations follow the
production install guide instead; bin/kumwe-install walks the same
steps interactively.
Starting clean
For an empty installation, choose the blank datasets in .env before the first migration:
KUMWE_SITE_CONTENT_PROFILE=blank KUMWE_BUSINESS_PROFILE=none
Then run the same database:migrate and create the first administrator with user:create-admin as
above. Each dataset's choice is frozen independently when its first reconciliation begins; later
migration runs refuse a different value rather than switching profiles, so decide before the first
migrate. With none selected, demo:install skips the demonstration cast cleanly and can still
install the example extensions if you want them. See demo profiles for the
selector contract.
Running it
The development Compose stack runs three services: app (the PHP built-in server behind a dedicated
asset router, plus a watcher that keeps the extension runtime verified), database (MariaDB by
default; MySQL and PostgreSQL are supported), and redis. docker compose up -d --wait returns only
once /health/ready answers. KUMWE_HTTP_PORT in .env moves the published port.
Background work is real infrastructure, not an afterthought. Queued report exports are completed by a
worker on the exports queue — without one they stay queued forever:
php bin/kumwe queue:work --queue=default --sleep-ms=1000 php bin/kumwe queue:work --queue=exports --sleep-ms=1000 php bin/kumwe schedule:run --loop
Production Compose runs the web, PHP-FPM, one-shot migrate, database, and Redis services, and starts the same worker and scheduler commands as dedicated services:
docker compose -f compose.production.yaml --profile automation up -d worker scheduler
Workers and scheduler covers queues, schedules, and operating rules; operations covers deployment, backup, and upgrades.
Testing
composer qa
That is the merge gate. Its parts run individually:
composer architecture:policy # layer and dependency policy composer cs # PSR-12 layout, 120-character lines composer analyse # PHPStan at level max composer docs:api # documentation-block completeness composer openapi:check # the compiled REST contract is current composer translation:check # the compiled message catalogues are current composer translation:strings # no template carries user-facing text inline composer assets:direction # no stylesheet pins a rule to one writing direction composer test:unit # unit suite composer test:integration # integration suite (needs the database)
The browser suite runs against the started stack:
npm ci npm run check npm run build npm run test:browser
Every supported engine — MariaDB, MySQL 8.4, PostgreSQL 17 — runs the same services and migrations;
select one per installation with DB_DRIVER and KUMWE_DATABASE_IMAGE and re-run the same suites.
Development and testing documents the local and CI contracts;
CONTRIBUTING.md and AGENTS.md describe the workflow.
Contributing and extending
- Read
AGENTS.mdfirst; the coding standard is normative for every contributor, human or automated. - Scaffold an extension with
php bin/kumwe extension:scaffoldand build against extensions and templates; everything installs through the signed pipeline. - Demonstration data is packaged as versioned demo profiles. Build a site,
then turn it into a shareable, installable profile with
php bin/kumwe demo:export-profile— forks ship their own demonstrations by dropping a profile beside the released ones. - Report problems and propose changes on GitHub issues and discussions.
Supported runtime
| Layer | Supported choice |
|---|---|
| PHP | 8.5 |
| Database | MariaDB current LTS (default), MySQL 8.4 LTS, PostgreSQL 17 |
| Persistence | Doctrine DBAL 4 with one portable schema and repository boundary |
| Redis | Current Redis 8 image line for cache, locks, rate limits, and coordination |
| Web | nginx and PHP-FPM release images |
The machine-readable API contract is api/openapi/kumwe-v1.json. Run
php bin/kumwe list from an installed release for the CLI command index.
License
Copyright (C) 2022–2026 Vast Development Method.
Kumwe is licensed under the GNU General Public License version 2.0; see LICENSE.