Fetch CML
Downloads the ConstraintModel blob from a source org and displays it in the editor. You can then review it or download it as a .cml file.
Fields
| Field | Description |
| -s Source Org | Alias or username of the org to fetch from. Must be authenticated via sf org login. |
| -m Model Name | The ExpressionSetDefinition.DeveloperName of the constraint model. Populated automatically from the org once you enter an alias. |
| --version-id | Alternative to Model Name. Use the explicit ExpressionSetDefinitionVersion record ID. |
Workflow
1. Type your org alias in Source Org — the Model dropdown loads automatically.
2. Select the model from the dropdown.
3. Click Fetch CML.
4. Review the syntax-highlighted CML in the Monaco editor.
5. Use Download .cml to save a local copy.
The model dropdown is cached per org. Click Refresh Orgs (↻) in the header to bust the cache.
If the model status is Draft, the CML blob may be empty. This is expected — the model was created but no CML has been uploaded yet.
CLI equivalent
node cli.js fetch -s <orgAlias> -m <ModelName> -o out.cml
node cli.js fetch -s <orgAlias> --version-id 9QBbZ0000000eezWAA
Deploy CML
Uploads CML source code from the editor to a target org by base64-encoding it and PATCHing the ConstraintModel blob field on the ExpressionSetDefinitionVersion record.
Fields
| Field | Description |
| -t Target Org | Alias or username of the destination org. |
| -m Model Name | Auto-discovers the latest ExpressionSetDefinitionVersion ID. Populated from org once alias is entered. |
| --version-id | Deploy directly to a specific version ID (skips the SOQL lookup). |
| CML Source | Paste or type your CML in the Monaco editor below. |
Two scenarios
Scenario A — Model already exists: The model and its version record are already in the target org. Just select it from the dropdown and paste the CML.
Scenario B — Model does not exist: You must first deploy the ExpressionSetDefinition metadata XML via the Salesforce CLI with status set to Inactive, then use this Deploy tab.
HTTP 204 means success. Salesforce does not return a body on a successful blob PATCH.
CLI equivalent
node cli.js deploy -t <orgAlias> -m <ModelName> ./model.cml
node cli.js deploy -t <orgAlias> --version-id 9QBbZ0000000eezWAA ./model.cml
Copy CML
Fetches the CML blob from a source org and immediately deploys it to a target org — no local file needed. The same model name must exist in both orgs.
Fields
| Field | Description |
| -s Source Org | Org to pull the CML from. |
| -t Target Org | Org to push the CML into. |
| -m Model Name | The ExpressionSetDefinition.DeveloperName. Must exist in both orgs with the same name. |
The arrow diagram updates live as you type, showing you the direction of transfer and the selected model name.
If the model does not exist in the target org, use Scenario B in the Deploy tab to create the definition first.
CLI equivalent
node cli.js copy -s <sourceOrg> -t <targetOrg> -m <ModelName>
Upload & Deploy
Upload a local .cml file from disk and deploy it directly — no copy-paste required. Supports drag-and-drop.
Fields
| Field | Description |
| -t Target Org | Org to deploy the file into. |
| -m Model Name | Select from dropdown — auto-loaded from org. |
| --version-id | Optional alternative to model name. |
| CML File | Click the drop zone to browse, or drag a .cml file onto it. |
Use Fetch to pull a CML file down, then use Upload & Deploy with the saved file to push it to a different org — a safe two-step migration.
Key Concepts
Why CML needs special handling
CML source code is stored as a binary blob inside a Salesforce record — not as standard metadata. The Salesforce CLI sf project retrieve/deploy commands only transfer the XML envelope, not the actual constraint rules.
Object model
| Object | Role |
| ExpressionSetDefinition | Container record. Stores the name, type (Constraint), and linked Context Definition. |
| ExpressionSetDefinitionVersion | Version record. Stores version number and status (Active / Draft / Inactive). |
| ConstraintModel | Binary blob field on the Version record. Holds the actual CML source, base64-encoded. |
What travels with the CML blob
✓ All CML types, relations, variables, annotations
✓ All constraint rules (require, constraint, message)
✓ Attribute definitions and default values
✓ Virtual type declarations and @sourceContextNode bindings
What does NOT travel
Product Classification Mappings — org-specific, must be manually reconfigured.
Context Definition (SalesTransactionContextExt) — must be deployed separately.
Custom Fields via @tagName — fields and their Context Definition mappings must exist.
API version
This tool uses Salesforce REST API v66.0. The endpoint used is:
/services/data/v66.0/sobjects/ExpressionSetDefinitionVersion/{versionId}/ConstraintModel
CLI Reference
All web UI operations are also available as a CLI. Run from the project root:
List orgs
node cli.js orgs
Fetch
node cli.js fetch -s <orgAlias> -m <ModelName> [-o output.cml]
node cli.js fetch -s <orgAlias> --version-id <id>
Deploy
node cli.js deploy -t <orgAlias> -m <ModelName> ./model.cml
node cli.js deploy -t <orgAlias> --version-id <id> ./model.cml
Copy (direct org-to-org)
node cli.js copy -s <sourceOrg> -t <targetOrg> -m <ModelName>
Start web UI
node cli.js serve --port 3000
npm start
Prerequisites
| Requirement | Check |
| Salesforce CLI | sf --version |
| Node.js ≥ 18 | node --version |
| Authenticated orgs | sf org list |
Run node cli.js --help or node cli.js <command> --help for full option descriptions.