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. |
# 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:
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:
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#
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:
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#
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#
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:
php artisan migrate --path=plugins/Article/database/migrations --realpath
Cache#
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#
php artisan serve
yarn dev # Vite for admin + storefront assets
yarn build:plugin article # one plugin's admin bundle
php artisan storage:link