Cogeze
Reference

CLI

Artisan commands Cogeze adds, and the Laravel ones whose behaviour it changes.

hub:preview#

Renders a public page through the full pipeline — renderer, theme, document shell — with optional fake data, without touching the database.

php artisan hub:preview <intent> [--param=key=value]... [--data=JSON] [--out=FILE]
Option Meaning
--param A route parameter, repeatable: --param=slug=hello.
--data JSON object. Keys replace the matching needs; the rest resolve normally.
--out Write HTML to a file instead of stdout.
bash
# real data
php artisan hub:preview article.show --param=slug=hello

# fake data — no database access for that need
php artisan hub:preview article.show --param=slug=x \
  --data='{"article":{"name":"Example","content":"<p>Body</p>"}}'

# partial data: is the view actually null-safe?
php artisan hub:preview article.show --param=slug=x --data='{"article":{"name":"Only a title"}}'

php artisan hub:preview article.index --out=/tmp/index.html

The last form is the useful one. A view that renders with a half-filled DTO will also survive a disabled plugin; one that crashes here will 500 in production the first time an optional field is null.

Plugin management#

Installing and uninstalling happens through the admin UI, which runs conflict checks first. From the CLI, drive the installer directly:

bash
php artisan tinker --execute="
\$m = app(App\Plugins\PluginManager::class);
\$i = app(App\Plugins\PluginInstaller::class);
\$p = \$m->find('article');

print_r(\$i->routeConflicts(\$p));   // URL clashes — must be empty
print_r(\$i->pageIssues(\$p));       // SSR/renderer problems — must be empty
\$i->install(\$p);
"

Always run both checks before installing outside the UI. They catch failures that are otherwise silent: a page shadowed by a static route never runs, and a page declaring SSR on a client-only renderer serves crawlers an empty shell.

Inspect what is installed:

bash
php artisan tinker --execute="
\$m = app(App\Plugins\PluginManager::class);
foreach (\$m->discover() as \$k => \$p) printf(\"%-16s %-12s %s\n\", \$k, \$p->category(), \$p->name());
"

Routing#

bash
php artisan route:list --path=blog        # what the Hub generated
php artisan route:list --path=api/admin   # plugin admin APIs

Hub routes are named hub.{intent}, or hub.{locale}.{intent} for localised variants.

Inspect the URL table directly:

bash
php artisan tinker --execute="
foreach (DB::table('route_map')->where('surface','public')->orderBy('priority')->get() as \$r)
  printf(\"%-5d %-18s %-28s %s\n\", \$r->priority, \$r->intent, \$r->pattern, \$r->locale ?? 'default');
"

route:cache#

bash
php artisan route:cache
php artisan route:clear

Safe to use — public routes are backed by an invokable controller, not closures. The caveat is staleness, and Cogeze clears the cache automatically whenever routing structure changes. See Deployment.

Database#

bash
php artisan migrate                 # core + mandatory plugins
php artisan migrate --seed          # then installs every plugin found on disk
php artisan migrate:fresh --seed    # destroys all data

Plugin migrations are not in the default path. They run through the installer when the plugin is installed, and roll back when it is uninstalled.

Run one plugin's migrations manually:

bash
php artisan migrate --path=plugins/Article/database/migrations --realpath

Cache#

bash
php artisan cache:clear
php artisan config:clear
php artisan optimize          # config + route + view + event
php artisan optimize:clear

Clearing the application cache also drops the route map cache and page-need entries. The next request rebuilds them from the database.

Development#

bash
php artisan serve
yarn dev                      # Vite for admin + storefront assets
yarn build:plugin article     # one plugin's admin bundle
php artisan storage:link