CLI Reference
Preview Feature: CLI AI Automation is a preview feature. If you encounter any issues, please report them at support.skipper18.com.
Complete reference for all Skipper CLI verbs and patch operations. Every verb emits a single JSON envelope on stdout.
Verbs
| Verb | Description |
|---|---|
| help | List available verbs or show detail for one verb |
| validate | Validate project consistency and migration freshness |
| export | Full export: classes + migrations using the project's configured framework |
| export-classes | Export classes/models only |
| export-migrations | Export migrations only |
| create-migration | Create a new migration revision |
| create-project | Create an empty project with chosen ORM/MVC framework |
| schema-summary | Dump entire project as structured JSON |
| import-project | Scan a codebase directory and build a .skipper from discovered files |
| import-database | Reverse-engineer a .skipper from a live database |
| compare | Diff two .skipper files using the migration diff engine |
| apply-patch | Apply a list of explicit operations to a project (RFC 6902 spirit) |
| apply-merge | Apply a declarative sparse target state (RFC 7396 spirit) |
| export-diagram | Render schema diagram as PNG or PDF (GUI builds only) |
| list-frameworks | List available ORM and MVC frameworks |
Verb Details
help
Skipper.exe -cli-help [<verb-name>]Lists all available verbs, or shows detailed usage for one verb. Returns UNKNOWN_VERB if the verb name is not recognised.
validate
Skipper.exe -cli-validate <project.skipper>Data: { issues: [{severity, code, object, message}], summary: {error_count, warning_count} }
Errors: PROJECT_LOAD_FAILED, VALIDATION_FAILED.
export
Skipper.exe -cli-export <project.skipper>Data: { files_written: [{path, bytes}], framework: "...", output_dir: "..." }
Errors: PROJECT_LOAD_FAILED, EXPORT_FAILED.
Files are written relative to the project file location, into each module's export_path.
export-classes
Skipper.exe -cli-export-classes <project.skipper>Export classes/models only. Currently returns NOT_IMPLEMENTED; use -cli-export for full export.
export-migrations
Skipper.exe -cli-export-migrations <project.skipper>Export migrations only. Currently returns NOT_IMPLEMENTED; use -cli-export for full export.
create-migration
Skipper.exe -cli-create-migration <project.skipper>Data: { created: true } (success) or { created: false, reason: "no_changes_pending" } (no changes).
Errors: MIGRATIONS_DISABLED.
create-project
Skipper.exe -cli-create-project -output <path> -orm <name> -mvc <name> [-name <project-name>]Creates an empty .skipper file with the chosen ORM and MVC framework.
Data: { output_path: "...", orm: "...", mvc: "..." }
Errors: UNKNOWN_FRAMEWORK, IO_ERROR, VIEWER_LICENSE.
schema-summary
Skipper.exe -cli-schema-summary <project.skipper> [-with-visual]Data: { project: {...} } -- see the Schema JSON Format page for the full structure.
import-project
Skipper.exe -cli-import-project <scan-dir> -output <path> -orm <name> -mvc <name> [-name <project-name>]Scans a codebase directory and builds a .skipper from discovered files.
Data: { output_path: "...", orm: "...", mvc: "...", modules_created: <int>, entities_imported: <int> }
Errors: IO_ERROR, VIEWER_LICENSE.
import-database
Skipper.exe -cli-import-database -output <path> -db-class <sqlite|mysql|postgres|sqlserver> -connection <conn> -orm <name> -mvc <name> [-name <project-name>] [-skip-initial-migrations]Reverse-engineers a .skipper from a live database connection.
Errors: DB_CONNECTION_FAILED, DB_IMPORT_FAILED, UNKNOWN_FRAMEWORK, VIEWER_LICENSE.
compare
Skipper.exe -cli-compare <new.skipper> <old.skipper>Data: { summary: {added, removed, modified, identical}, items: [{action, type, name, details?}] }
Diffs two .skipper files using the migration diff engine.
apply-patch
Skipper.exe -cli-apply-patch <project.skipper> -patch <ops.json> -output <out.skipper>Data (success): { ops_executed: <int>, output_path: "..." }
Data (failure): { ops_attempted: <int>, failed_op_index: <int> }
Errors: INVALID_OP, OBJECT_NOT_FOUND, MALFORMED_INPUT_FILE.
On failure, the output file is not written. Retry with the original input file.
apply-merge
Skipper.exe -cli-apply-merge <project.skipper> -merge <state.json> -output <out.skipper>Data: { objects_changed: <int>, output_path: "..." }
Errors: INVALID_MERGE_INPUT, OBJECT_NOT_FOUND, MALFORMED_INPUT_FILE.
See the Merge Input Format section below for the expected JSON structure.
export-diagram
Skipper.exe -cli-export-diagram <project.skipper> -format <png|pdf> -output <path>Data: { format: "...", output_path: "...", bytes: <int> }
Errors: INVALID_ARG_VALUE, NOT_IMPLEMENTED (svg). Available in Skipper.exe (GUI build), not in SkipperCli.exe (console build). On Linux set QT_QPA_PLATFORM=offscreen.
list-frameworks
List available ORM and MVC frameworks.
Skipper.exe -cli-list-frameworksData: { orm_frameworks: [{name: "..."}], mvc_frameworks: [{name: "..."}] }
Patch Operations
The apply-patch verb accepts a JSON file containing an ordered list of operations. The format follows the spirit of RFC 6902 (JSON Patch). Each operation is an object with op (the operation name) and args (an object of arguments). The top-level structure is:
{"ops": [{"op": "name", "args": {...}}, ...]}There are 36 operations in total. Operations are executed in order. If any operation fails, execution stops and the failure index is reported. On failure, the output file is not written. Retry with the original input file. Required arguments are shown in bold; optional arguments are in [brackets].
Entity Operations
| Operation | Arguments | Description |
|---|---|---|
| add_entity | module, name, [namespace], [description] | Create a new entity in the specified module. Auto-creates an id integer PK field from the framework template. Do not add PK manually. |
| update_entity | entity, [name], [namespace], [description] | Update properties of an existing entity |
| remove_entity | entity | Delete an entity and all its children. Also removes associated fields, associations, indexes, and M:N relationships. |
Field Operations
| Operation | Arguments | Description |
|---|---|---|
| add_field | entity, name, [type], [size], [primary], [nullable], [unique], [auto_increment], [default] | Add a new field to an entity. If a field with the same name already exists, the operation is silently skipped. Fields are NOT NULL by default; pass nullable: true explicitly. |
| update_field | entity, field, [name], [type], [size], [primary], [nullable], [unique], [auto_increment], [default] | Update properties of an existing field |
| remove_field | entity, field | Delete a field from an entity |
| reorder_field | entity, field, sort_order | Change the sort position of a field within its entity |
Association Operations
| Operation | Arguments | Description |
|---|---|---|
| add_association | from, to, [owner_alias], [inverse_alias] | Create a new association between two entities |
| update_association | id, [owner_alias], [inverse_alias] | Update alias names on an existing association |
| remove_association | id | Delete an association |
Module Operations
| Operation | Arguments | Description |
|---|---|---|
| add_module | name, [namespace], [description], [export_path], [export_format] | Create a new module in the project |
| update_module | module, [name], [namespace], [description], [export_path], [export_format] | Update properties of an existing module |
| remove_module | module | Delete a module and all its contents |
Index Operations
| Operation | Arguments | Description |
|---|---|---|
| add_index | entity, name, [unique], [fields: ["f1", "f2"]] | Create a new index on an entity |
| update_index | entity, index (name), [name], [unique] | Update properties of an existing index. The index argument is the index name (string), not a numeric ID. |
| remove_index | entity, index (name) | Delete an index from an entity. The index argument is the index name (string), not a numeric ID. |
Many-to-Many Operations
| Operation | Arguments | Description |
|---|---|---|
| add_many_to_many | owner, inverse, [mn_entity], [owner_alias], [inverse_alias] | Create a many-to-many relationship between two entities. Automatically creates a join entity with composite PK foreign key fields. |
| update_many_to_many | id, [owner_alias], [inverse_alias] | Update alias names on an existing many-to-many |
| remove_many_to_many | id | Delete a many-to-many relationship |
Embedded Operations
| Operation | Arguments | Description |
|---|---|---|
| add_embedded | from, to, [owner_alias], [inverse_alias] | Create an embedded relationship |
| update_embedded | id, [owner_alias], [inverse_alias] | Update alias names on an existing embedded |
| remove_embedded | id | Delete an embedded relationship |
Inheritance Operations
| Operation | Arguments | Description |
|---|---|---|
| add_inheritance | parent, child, [type], [discriminator_value] | Create an inheritance relationship between entities. Valid types: SINGLE_TABLE, JOINED, MAPPED_SUPERCLASS. |
| update_inheritance | id, [discriminator_value] | Update the discriminator value of an inheritance |
| remove_inheritance | id | Delete an inheritance relationship |
Region Operations
| Operation | Arguments | Description |
|---|---|---|
| add_region | module, [caption], [namespace], [description] | Create a visual region in a module |
| update_region | id, [caption], [namespace], [description] | Update properties of an existing region |
| remove_region | id | Delete a region |
Comment Operations
| Operation | Arguments | Description |
|---|---|---|
| add_comment | module, [caption], [description] | Create a comment object in a module |
| update_comment | id, [caption], [description] | Update an existing comment |
| remove_comment | id | Delete a comment |
ORM Attribute Operations
| Operation | Arguments | Description |
|---|---|---|
| set_orm_attribute | object, [object_type], path, value | Set a framework-specific ORM attribute value |
| remove_orm_attribute | object, [object_type], path | Remove an ORM attribute |
| add_orm_attribute_item | object, [object_type], path, [key], [values] | Add an item to a list-type ORM attribute. The values parameter accepts child key-value pairs (e.g. lifecycle callbacks). |
| remove_orm_attribute_item | object, [object_type], path | Remove an item from a list-type ORM attribute |
The object_type argument defaults to "entity". Supported types for ORM attribute write operations: entity, field, module, association. Schema-summary emits orm_attributes on all object types (including index, many-to-many, embedded, region) but write operations for those types are not yet implemented.
Visual Layout Operations
| Operation | Arguments | Description |
|---|---|---|
| reset_layout | {} (no args) | Resets visual positions on all entities/modules/regions/comments so auto-arranger runs on next GUI open |
Field ORM Attribute Addressing
For object_type: "field", use one of these formats to identify the field:
| Format | Example | Notes |
|---|---|---|
| Dotted notation (recommended) | "object": "Customer.email" | Entity.field format |
| With entity parameter | "object": "email", "entity": "Customer" | Separate entity lookup |
| Field name only | "object": "email" | Searches all entities; fails if ambiguous |
Examples:
{"op": "set_orm_attribute", "args": {"object": "Product.price", "object_type": "field", "path": "precision", "value": "10"}}
{"op": "set_orm_attribute", "args": {"object": "price", "object_type": "field", "entity": "Product", "path": "scale", "value": "2"}}
{"op": "add_orm_attribute_item", "args": {"object": "Product", "path": "lifecycle-callbacks", "values": {"type": "prePersist", "method": "onPrePersist"}}}Attribute Paths
Use attribute names without framework prefix. Write table not orm:table. Use / to separate nested paths (e.g. options/charset). The orm: prefix is auto-stripped if present, but should be avoided.
{"op": "set_orm_attribute", "args": {"object": "Product", "path": "table", "value": "app_products"}}
{"op": "set_orm_attribute", "args": {"object": "Product", "path": "options/charset", "value": "utf8mb4"}}Name Resolution
Entity and module names accept short names (Customer, MainBundle) or fully qualified names (\Customer, \MainBundle). Short names are matched against LocalName.
Ambiguity: If two entities share the same short name in different modules (e.g. \App\Crm\Address and \App\EShop\Address), the short name Address matches the first one found. Use the fully qualified name to disambiguate.
Index and Association Referencing
update_index and remove_index use the index name (string), not a numeric ID. Example: {"op": "remove_index", "args": {"entity": "Customer", "index": "idx_email"}}
update_association, remove_association, update_many_to_many, and remove_many_to_many require a numeric id from -cli-schema-summary output. IDs are project-scoped auto-increment numbers.
Merge Input Format
The -cli-apply-merge verb accepts a JSON file with a project root key mirroring schema-summary structure. Only include objects you want to change — unmentioned objects are left as-is. Merge updates existing fields by name and adds new ones.
{
"project": {
"modules": [
{
"name": "MainBundle",
"entities": [
{
"name": "Customer",
"fields": [
{"name": "email", "type": "string", "size": 320},
{"name": "middleName", "type": "string", "size": 100, "nullable": true}
]
}
]
}
]
}
}Global Flags
| Flag | Effect |
|---|---|
-quiet | Suppress stderr diagnostics |
-verbose | Raise stderr to debug level (trace + progress) |
-include-timing | Add meta.timing_breakdown to envelope |