@creopse/cli
v0.0.18
Published
Creopse CLI tools
Downloads
442
Readme
Creopse CLI
A command-line utility for managing content (sections, widgets, pages, content models, menus), media, base information, and plugin scaffolding in the Creopse ecosystem (Vue or React). Each command is a thin wrapper around the corresponding php artisan creopse:* / plugin:make-* command.
Requirements
- A Laravel project with Creopse installed
- PHP available in your
PATH(the CLI shells out tophp artisan) - Node.js 18+ (for the CLI itself)
Installation
npm install -g @creopse/cliAfter installation you can run the CLI from anywhere inside your Laravel project with the creopse command. Use creopse --help to list all groups or creopse <group> --help to inspect a specific group.
Usage
creopse [command] [options]Global conventions:
- Group aliases let you type less:
sec↔section,wid↔widget,pag↔page,cm↔content-model,men↔menu,med↔media,info↔base-info,plg↔plugin,perm↔permalink. - Subcommand aliases: every
add/make,remove/delete,edit/updatepair shares the same underlying command, sosection addandsection makeare equivalent. - JSON options (
--data,--settings,--data-structure,--settings-structure,--metadata) accept either an inline JSON string or a@path/to/file.jsonreference (the@prefix loads the file). - Localized options (
--title,--description,--link-title) are repeatable and take alocale:valuepair, e.g.--title "en:Home"--title "fr:Accueil". - The internal
--aliasflag exposed by the underlying artisan commands is not forwarded by the CLI — use the documented subcommand names/aliases instead.
Commands
creopse install
Bootstraps the Creopse package into your Laravel project (publishes configuration, frontend assets, and the base structure for Vue or React). Run this first, before using any other command, from the root of your Laravel app.
| Option | Description |
|---|---|
| -t, --template <template> | Frontend template (vue or react, default: vue) |
| --no-force | Disable force mode (enabled by default, overwrites existing files) |
creopse install # install with the default Vue template
creopse install -t react # install with the React template
creopse install --no-force # install without overwriting existing filescreopse section (alias sec)
Sections are reusable, translatable UI blocks rendered by your frontend (a .vue or .tsx component in resources/js/components/sections). This group both generates the component file and registers a database entry describing the section (title per locale, data structure, settings structure).
| Subcommand | Alias | Description |
|---|---|---|
| add <name...> | make | Add one or more section components and DB entries |
| remove <name...> | delete | Remove one or more section components and DB entries |
| edit <name> | update | Update title (per locale), data structure, and/or settings structure |
- add options (single name only):
-t/--title <locale:value>(repeatable),--data-structure <json>,--settings-structure <json>. - remove options:
-f/--force(skip the confirmation prompt). - edit options:
-t/--title <locale:value>(repeatable),--data-structure <json>,--settings-structure <json>.
creopse section add HeroBanner # single section (PascalCase name)
creopse section add HeroBanner ContactForm Footer # multiple sections at once
creopse section add HeroBanner --title "en:Hero" --title "fr:Héros" --data-structure '{"fields":[{"type":"text","name":"heading"}]}'
creopse section edit HeroBanner --title "en:Hero - Video"
creopse section remove HeroBanner
creopse section remove HeroBanner Footer --force # no confirmation promptcreopse widget (alias wid)
Widgets are smaller reusable components (rendered in resources/js/components/widgets). Unlike sections they do not carry a database structure — add generates the component file, remove deletes it.
| Subcommand | Alias | Description |
|---|---|---|
| add <name...> | make | Add one or more widget components |
| remove <name...> | delete | Remove one or more widget components (-f/--force) |
creopse widget add NewsletterForm
creopse widget add NewsletterForm SocialLinks
creopse widget remove NewsletterForm --forcecreopse page (alias pag)
Pages are the top-level content entities. A page has a title, optional content, and a display position. Sections are not created with the page — they are attached afterwards via the section-instance subcommands below, which control per-instance data, ordering, and visibility.
| Subcommand | Alias | Description |
|---|---|---|
| add <name> | make | Create an empty page (sections attached separately) |
| edit <name> | update | Update title, content, and/or position |
| remove <name> | delete | Delete a page (-f/--force) |
| attach-section <page> <section> | | Attach a section instance to a page |
| detach-section <page> <section> | | Detach a specific section instance (-f/--force) |
| order-sections <page> | | Set the display order of a page's sections |
| set-section-source <page> <section> | | Set/clear the data source page for a section instance |
| toggle-section-status <page> <section> | | Enable or disable a section instance |
| update-section-content <page> <section> | edit-section-content | Update a section instance's title/data/settings |
- add / edit options:
-t/--title <locale:value>(repeatable),--content <text>,--position <number>(add default:0). - attach-section options:
--link-id <id>(defaultdefault— lets the same section appear multiple times on a page),--link-title <locale:value>(repeatable),--data <json>,--settings <json>,--source-page <name>(copy data from another page's instance),--source-link-id <id>(defaultdefault). - order-sections options:
--item <section:link-id>(repeatable, in the desired order). - set-section-source options:
--link-id <id>,--source-page <name>(usenoneto clear),--source-link-id <id>. - toggle-section-status options:
--link-id <id>,--disabled <bool>(defaulttrue— passfalseto enable). - update-section-content options:
--link-id <id>,--link-title <locale:value>(repeatable),--data <json>,--settings <json>.
creopse page add home --title "en:Home" --title "fr:Accueil" --position 1
creopse page edit home --content "<h1>Welcome</h1>" --position 2
creopse page remove home --force
# Attach two instances of the same section with different data
creopse page attach-section home HeroBanner --link-id top --link-title "en:Hero Top"
creopse page attach-section home HeroBanner --link-id bottom --data '{"heading":"Footer hero"}'
# Reorder them and disable the bottom one
creopse page order-sections home --item "HeroBanner:top" --item "HeroBanner:bottom"
creopse page toggle-section-status home HeroBanner --link-id bottom --disabled true
# Source the bottom instance's data from the "landing" page instead
creopse page set-section-source home HeroBanner --link-id bottom --source-page landing
# Update a single instance's content
creopse page update-section-content home HeroBanner --link-id top --data '{"heading":"Updated"}'
# Detach it
creopse page detach-section home HeroBanner --link-id top --forcecreopse content-model (alias cm)
Content models are structured, translatable content types (think "articles", "products", "team members"). A model defines a data structure; items are the actual records. Useful for editorial content, user data, or system data.
| Subcommand | Alias | Description |
|---|---|---|
| add <name> <intent> <access-scope> | make | Create a content model |
| remove <name> | delete | Delete a content model (-f/--force) |
| edit <name> | update | Update a content model |
| item-add <content-model> | item-make | Create a content model item |
| item-remove <id> | item-delete | Delete a content model item (-f/--force) |
| item-edit <id> | item-update | Update a content model item |
intent:editorial-content(CMS-style content),user-data(data owned by users), orsystem-data(internal/system records).access-scope:internal(managed via code/API only) oruser-editable(exposed in the admin UI for editors).- add options:
--title/--description(repeatable),--image <value>(path or URL),--data-structure <json>,--title-field-name <value>(which structure field is used as the display title),--has-permalink <bool>. - edit options: same as add plus
--intent <value>,--access-scope <value>. - item-add options:
--title(repeatable),--data <json>,--is-active <bool>(defaulttrue),--created-by-type <value>(user,admin, orsystem, defaultsystem). - item-edit options:
--content-model <name>(move the item to another model),--title(repeatable),--data <json>,--is-active <bool>,--created-by-type <value>.
# Create an editorial "Article" model with a permalink
creopse content-model add article editorial-content user-editable \
--title "en:Article" --title "fr:Article" \
--data-structure '{"fields":[{"name":"body","type":"richtext"}]}' \
--title-field-name body --has-permalink true
# Add two articles (data loaded from files)
creopse content-model item-add article --title "en:First post" --data '@article-1.json'
creopse content-model item-add article --title "en:Second post" --is-active false
# Update one and move it to another model
creopse content-model item-edit 12 --title "en:Renamed" --content-model article-draft
# Remove a model and its items
creopse content-model remove article --forcecreopse permalink (alias perm)
Permalinks map a path prefix to a piece of content (a news tag/category/article, or a content model item) and, optionally, the page/template that renders it.
| Subcommand | Alias | Description |
|---|---|---|
| add <path-prefix> <content-type> | make | Create a permalink |
| remove | delete | Delete a permalink (-f/--force) |
| edit | update | Update a permalink |
content-type:news-tag,news-category,news-article, orcontent-model.- add options:
--content-id <value>(required whencontent-type=content-model; numeric ID or content model name),--content-param <value>(content param used to resolve the target, e.g.idorslug, defaultid),--page <name>(page/template used to render this content). - remove/edit identify the target permalink with exactly one of
--id <id>,--path-prefix <prefix>, or--content-model <name>. - edit update options:
--new-path-prefix <prefix>,--content-param <value>,--page <name>(noneto unset). The content target itself cannot be changed once set.
# A permalink for a content model, resolved by slug
creopse permalink add /articles content-model --content-id article --content-param slug --page article-page
# A permalink for news articles
creopse permalink add /news news-article --page news-page
# Update it, identified by its current path prefix
creopse permalink edit --path-prefix /articles --new-path-prefix /blog
# Remove it, identified by its content model
creopse permalink remove --content-model article --forcecreopse menu (alias men)
Menus drive site navigation. A menu is assigned to a location (e.g. header, footer); menu items are the links/entries; groups and types are taxonomy used to categorize and style items.
| Subcommand | Alias | Description |
|---|---|---|
| add <name> | make | Create a menu |
| remove <name> | delete | Delete a menu (-f/--force) |
| edit <name> | update | Update a menu |
| item-add <menu> | item-make | Create a menu item |
| item-remove <id> | item-delete | Delete a menu item (-f/--force) |
| item-edit <id> | item-update | Update a menu item |
| item-group-add <name> | item-group-make | Create a menu item group |
| item-group-remove <name> | item-group-delete | Delete a menu item group (-f/--force) |
| item-group-edit <name> | item-group-update | Update a menu item group |
| item-type-add <name> | item-type-make | Create a menu item type |
| item-type-remove <name> | item-type-delete | Delete a menu item type (-f/--force) |
| item-type-edit <name> | item-type-update | Update a menu item type |
| location-add <name> | location-make | Create a menu location |
| location-remove <name> | location-delete | Delete a menu location (-f/--force) |
| location-edit <name> | location-update | Update a menu location |
- menu add/edit options:
--title/--description(repeatable),--data <json>(menu parameters),--location <name>(assign to a location; edit acceptsnoneto unassign). - item-add/item-edit options:
--title/--description(repeatable),--path(internal path),--url(external URL),--controller(controller reference),--parent(ID of the parent item,noneto unset on edit),--position(display order),--target-type(external-link,page-link, orcontent-link),--is-active/--is-visible(booleans),--color,--icon,--image,--page(name of the linked page,noneto unset),--section-key,--menu-item-group,--menu-item-type(names,noneto unset on edit),--content-type(news-tag,news-category,news-article, orcontent-model),--content-id(target content name/id). - group/type/location add options:
--description(repeatable). edit options:--new-name <name>,--description(repeatable).
# Locations and taxonomy first
creopse menu location-add header --description "en:Site header"
creopse menu item-group-add featured --description "en:Featured entries"
creopse menu item-type-add dropdown --description "en:Dropdown item"
# Create the menu and assign it to the header location
creopse menu add main --title "en:Main Menu" --location header
# Items: a home link, an external link, and a dropdown child
creopse menu item-add main --title "en:Home" --page home --target-type page-link --position 1
creopse menu item-add main --title "en:Blog" --url "https://blog.example.com" --target-type external-link --position 2
creopse menu item-add main --title "en:About" --path "/about" --parent 1 --menu-item-type dropdown --menu-item-group featured
# Edit and reassign
creopse menu item-edit 3 --title "en:About Us" --is-visible false
creopse menu edit main --title "en:Primary Menu"
# Cleanup
creopse menu item-remove 3 --force
creopse menu location-remove header --forcecreopse media (alias med)
The media library stores files (images, videos, documents) as MediaFile records. Note the distinction: a file lives on disk, a record is the database entry. You can delete either independently.
| Subcommand | Alias | Description |
|---|---|---|
| upload <path> | add | Upload a local file to the media library |
| replace <id> <path> | | Replace a media file's underlying file |
| remove-file <path> | | Delete a file from disk (-f/--force) |
| remove-record <id> | | Delete a MediaFile record (--permanent, -f/--force) |
| restore <id> | | Restore a soft-deleted MediaFile record |
| purge | | Permanently delete all soft-deleted records (-f/--force) |
- upload options:
--folder <name>(storage folder, defaultuploads),--filename <name>(override display name),--metadata <json>(merged with auto-extracted image metadata),--sender <id>(user the upload is attributed to). - replace options:
--folder <name>(defaultuploads),--filename <name>,--metadata <json>. - remove-record flag:
--permanentforce-deletes (otherwise it is soft-deleted and can be restored).
creopse media upload ./assets/logo.png --folder branding --filename "Company Logo"
creopse media upload ./banner.jpg --metadata '{"alt":"Summer sale"}' --sender 1
# Replace the file behind record #42 without changing its id
creopse media replace 42 ./banner-v2.jpg
# Delete just the disk file, or just the record (soft delete by default)
creopse media remove-file branding/logo.png --force
creopse media remove-record 42
# Recover, or permanently purge all soft-deleted records
creopse media restore 42
creopse media purge --forcecreopse base-info (alias info)
Base information holds site-wide settings surfaced across the app: site name, contact details, branding, social links, etc. Update one or more entries at once using key=value pairs (long values can be loaded from a file with @path).
| Subcommand | Description |
|---|---|
| update <pairs...> | Update base information entries with key=value pairs (value can be @path/to/file) |
creopse base-info update name="My App" [email protected] phone="+33123456789"
creopse base-info update [email protected]
creopse base-info update facebook="https://facebook.com/myapp" twitter="https://twitter.com/myapp"creopse plugin (alias plg)
Generates Laravel classes (models, controllers, migrations, events, listeners, jobs, requests, seeders) inside a plugin instead of the host app. Each command takes the plugin id (vendor/plugin-name) and the class name, and resolves the plugin's namespace from its plugin.json.
| Subcommand | Description |
|---|---|
| make-model <plugin> <name> | Create an Eloquent model (-m/--migration, --namespace) |
| make-controller <plugin> <name> | Create a controller (-r/--resource, --namespace) |
| make-migration <plugin> <name> | Create a migration (--create <table>, --table <table>) |
| make-event <plugin> <name> | Create an event (--namespace) |
| make-listener <plugin> <name> | Create a listener (-e/--event <fqcn>, --queued, --namespace) |
| make-job <plugin> <name> | Create a queued job (--sync, --namespace) |
| make-request <plugin> <name> | Create a form request (--namespace) |
| make-seeder <plugin> <name> | Create a seeder (--namespace) |
--namespace <namespace>overrides the target PSR-4 namespace (otherwise derived from the plugin'splugin.json).make-migrationtakes--create <table>(to create a table) or--table <table>(to modify one) and has no--namespaceoption (migrations are not namespaced classes).make-listenerflags:-e/--event <fqcn>injects the handled event,--queuedmakes it queueable.make-jobflag:--syncgenerates a synchronous (non-queued) job.
# A model with its migration, generated inside the blog plugin
creopse plugin make-model vendor/blog Post --migration
creopse plugin make-controller vendor/blog PostController --resource
creopse plugin make-migration vendor/blog create_comments_table --create comments
# Events and listeners (note the FQCN for --event)
creopse plugin make-event vendor/blog PostPublished
creopse plugin make-listener vendor/blog SendPostNotification \
--event "Vendor\\Blog\\Events\\PostPublished" --queued
# A synchronous job and a seeder
creopse plugin make-job vendor/blog ImportPosts --sync
creopse plugin make-seeder vendor/blog PostsTableSeeder
# Override the namespace when generating into a sub-domain
creopse plugin make-model vendor/blog Post --namespace "Vendor\\Blog\\Domain\\Content"Examples
A realistic end-to-end flow combining several groups:
# 1. Install the package
creopse install -t vue
# 2. Build a homepage out of sections
creopse section add HeroBanner ContactForm Footer
creopse page add home --title "en:Home" --title "fr:Accueil" --position 1
creopse page attach-section home HeroBanner --link-id top --link-title "en:Hero Top"
creopse page attach-section home ContactForm --link-id main
creopse page attach-section home Footer --link-id bottom
creopse page order-sections home \
--item "HeroBanner:top" --item "ContactForm:main" --item "Footer:bottom"
# 3. Model some editorial content
creopse content-model add article editorial-content user-editable \
--title "en:Article" --has-permalink true
creopse content-model item-add article --title "en:Hello world" --data '@first-article.json'
# 4. Wire up navigation
creopse menu location-add header --description "en:Site header"
creopse menu add main --title "en:Main Menu" --location header
creopse menu item-add main --title "en:Home" --page home --target-type page-link
# 5. Media and branding
creopse media upload ./logo.png --folder branding
creopse base-info update name="My App" [email protected]
# 6. Scaffold plugin code
creopse plugin make-model vendor/blog Post --migration
creopse plugin make-controller vendor/blog PostController --resource
creopse plugin make-listener vendor/blog SendNotification \
--event "Vendor\\Blog\\Events\\PostPublished" --queuedDevelopment
pnpm install
pnpm run build # compile TypeScript to build/
pnpm run check:ts # type-check only (no emit)
pnpm test # run tests (Vitest)
pnpm test:watch # run tests in watch mode
pnpm run format # format with Prettier