This quickstart takes you from no CLI to a working loop. You create a repository that mirrors your tenant's customization, check that you are signed in, push a script change from your own editor, and watch its test run in a terminal. The CI recipes build on this: a pipeline repeats the same steps without a person at the keyboard.
Overview
The session has eight steps, and each one has a check you can see:
| Step | Command | What you should see |
|---|---|---|
| 1 | dotnet tool install | xmatix --version prints 0.1.0-alpha or later |
| 2 | xmatix init | "Initialized xMatix workspace at <path>" |
| 3 | xmatix login | Signed in as with your user name |
| 4 | xmatix doctor | A ✓ line for workspace, config, authority, clientId, scopes and token |
| 5 | xmatix snapshot export + xmatix scripts pull --all | Files under xmatix/, ready to commit |
| 6 | xmatix scripts push … --activate | "Created vN (compileOk=yes) [activated]" |
| 7 | xmatix scripts run | The test result, printed as JSON |
| 8 | xmatix runs tail --follow | The test run in the run feed |
The CLI is an early (alpha) release. Some commands still fail on a correct setup. This page tells you which ones, so you don't spend time fixing a setup that isn't broken.
When to use it
- You are setting up the CLI for the first time on your machine.
- You are starting a new repository for a tenant's configuration.
- You are joining a team that already has a workspace. Do Steps 1, 3 and 4 only, in the cloned repository.
How xMatix handles it
- The CLI acts as you. Every command calls the tenant's API with your own sign-in. It can never do more than your account is allowed to do in the product. See Permissions.
- The workspace is the folder that contains
.xmatix/. Each command starts in the current directory and walks up through the parent folders until it finds one. That folder's.xmatix/config.jsondecides which tenant the command acts on. See Workspace layout. - Settings are in the repository. Tokens are not.
loginwrites the tenant slug, API base URL, authority, client id and scopes into.xmatix/config.json. These are connection details, not secrets. Tokens are cached in your home folder under.xmatix/tokens/<tenant>/and protected by the operating system. See Authentication. - A push creates a version. Activating it is a separate choice. Every
scripts pushsaves and compiles a new version of the script on the server. The version runs only if you push with--activateand it compiles. - A test run uses the active version.
scripts runruns the script's active version against a record you name, and records the run so thatruns tailcan show it.
Prerequisites
- The .NET 10 SDK.
- A git repository, new or existing, to hold the tenant's configuration.
- Your tenant's connection values: the tenant slug, the API base URL, the sign-in authority URL and the CLI's registered client id. Your administrator has them. You enter them once and they are saved.
- On Linux, a running desktop keyring (secret service) for your user. The token cache is stored there.
- A user account with the capabilities for what you plan to pull and push (see Permissions), and at least one automation script in the tenant for Steps 6–8. Scripts are created under Setup → Process Studio → Scripts. The CLI can't create one.
- A record you can afford to change, for Step 7.
Procedure
- 1
Run xmatix --help after installation to verify the global command resolves.
- 2
login, whoami and logout manage tenant authentication without storing credentials in the repository.
- 3
init scaffolds the workspace; doctor validates configuration, token and API reachability.
- 4
Artifact commands round-trip scripts, metadata, rules, workflows, dashboards and reports.
- 5
snapshot and migrate orchestrate repository-wide comparison and deployment workflows.
Step 1 — Install the CLI
dotnet tool install -g xmatix.cli
xmatix --version
xmatix --help
The tool installs one global command, xmatix. --version proves the command resolves on your PATH. --help lists the commands this page uses: login, init, doctor, scripts, runs and snapshot. If a different program answers, check your global tool path before you go on. To update later, run dotnet tool update -g xmatix.cli and repeat both checks.
Step 2 — Create the workspace
In a terminal at your repository root, run:
xmatix init
init creates these files and folders. It never overwrites a file that is already there.
.xmatix/config.json, with empty connection values andapiVersionset tov1..xmatix/.gitignore, which keeps thecache/andtokens/folders inside.xmatix/out of git.xmatix/automation/scripts/, with an empty.gitkeepfile..vscode/tasks.json, with two editor tasks: one that pushes the script open in the editor (xmatix scripts pushon the current file) and one that pulls all scripts (xmatix scripts pull --all).
The CLI prints "Initialized xMatix workspace at <path>", lists the files and suggests xmatix login as the next step. Run init before you sign in. If you sign in first, the settings can land in the wrong folder (see Common problems).
Step 3 — Sign in
xmatix login --tenant <tenant> \
--api-base-url <api-url> \
--authority <authority-url> \
--client-id <client-id>
The CLI first saves the four values to .xmatix/config.json. Then it prints the Workspace, Tenant and API it is using, followed by the device-code instructions. Open the address it shows, enter the short code and sign in as yourself. When you finish, the CLI prints Signed in as with your user name and Token expires with the token's expiry time.
Check two things before you go on:
- Workspace is your repository root, not your home folder.
- API is your organization's API base URL. The API base URL decides which organization every command acts on. The tenant slug doesn't.
Add --scopes "<scope> <scope>" only if your administrator gives you specific scopes. After the first sign-in you can run plain xmatix login, because the saved values are reused. Run git status: .xmatix/config.json is the only new file under .xmatix/, and it holds no token or code.
Step 4 — Run the pre-flight checks
xmatix doctor
Doctor prints one line per check, in this order:
| Check | Passes when |
|---|---|
| workspace | A .xmatix/ folder is found from the current directory. The line shows the folder it found. |
| config | .xmatix/config.json can be read. The line shows the tenant and API. |
| authority, clientId | The value is set. |
| scopes | scopes in the config isn't empty. |
| folder (six lines) | The folder for scripts, rules, workflows, dashboards, reports or metadata exists. A missing folder is only a warning: "missing — created on first pull". |
| token | A token is available without signing in again. The line shows its expiry. |
| api | The identity call succeeds. |
Two checks fail on a correct setup in the current release:
- api always fails with "whoami failed" and a 404, because the CLI calls the identity endpoint at an address the API doesn't serve. Your sign-in is fine.
- scopes fails while
scopesis empty, even though sign-in works with an empty value. To clear it, setscopesin.xmatix/config.jsonto your API base URL followed by/.default, for examplehttps://<api-host>/.default. That is the same scope the CLI uses when the value is empty, so your cached token keeps working.
Because the api check always fails, doctor ends with "problem(s) detected" and exit code 1. Read the lines instead of the exit code. A ✓ on token means you are signed in. Then run xmatix scripts list as a real round trip to the API. It prints a table of scripts that ends with "N script(s)." Run doctor at the start of every working session and every CI job, so a sign-in problem isn't mistaken for a problem with your files.
Step 5 — Export the tenant and commit
xmatix snapshot export --skip scripts,dashboards,reports
xmatix scripts pull --all
snapshot export runs each kind's pull in turn into the xmatix/ folder tree. Skip three of the kinds, because of how the current release behaves:
- Scripts. The export's own scripts step always fails, because it runs
scripts pullwithout--all. Pull scripts separately, as shown. - Dashboards and reports. They don't round-trip yet. Their pull writes no files. See Dashboards and reports in the CLI.
The export prints a line for each pull and ends with "Snapshot export complete." or "Snapshot export finished with N failure(s)." scripts pull --all prints "Pulled <path> (vN)" for each script and ends with "Done. pulled=N skipped=N". A script with no active version is skipped. Each script goes into a folder named after the entity of its first binding, or _unbound, as a .csx file with a .meta.json file next to it.
Before you commit, review what you got:
xmatix/metadata/tenant-owned.jsonis a full seed pack. Pushing a full pack can delete metadata from a tenant. Read Metadata in the CLI before you push this file anywhere.- Look through the files for endpoint addresses or other values you don't want in a repository. Metadata exports include AI model endpoint addresses (never keys).
.xmatix/config.jsonholds connection values only.
Then commit:
git add xmatix/ .xmatix/config.json .xmatix/.gitignore .vscode/tasks.json
git commit -m "Initial tenant snapshot"
Don't expect a second export to produce an empty git diff. Every pull writes a new export time (generatedAtUtc) into the metadata file and a new lastPulledUtc time into every .meta.json file. Ignore those two lines when you compare exports. Any other change means the tenant changed.
Step 6 — Change a script and push it
Open a pulled script, for example xmatix/automation/scripts/Account/MyValidation.csx. Make an edit, then push it:
xmatix scripts push xmatix/automation/scripts/Account/MyValidation.csx --activate -m "first CLI change"
The push saves a new version of the script on the server and compiles it. -m stores a comment against the version, for example a git commit id. The result depends on what happened:
| Output | Exit code | What it means |
|---|---|---|
| "Created vN (compileOk=yes) [activated]" | 0 | Version N compiled and is now the active version. Its triggers run it from now on. |
| "Created vN (compileOk=no)" followed by the compile errors | 3 | Version N is saved with its errors but isn't active. The previous active version keeps running. Fix the file and push again. |
| "Server has a newer current version than your local copy." | 2 | Someone activated a different version after your pull. Pull, merge your change, and push again. --force skips this check. |
| "No changes vs current version (vN); nothing to push." | 0 | Your file matches the active version you last pushed with --activate. |
Without --activate, the push saves and compiles the version but nothing changes at run time. Use that when you want to stage a change without making it live. Activation changes live behaviour straight away, so review your diff first.
The compile errors use the file(line,col): error CSnnnn: message format that the push editor task from Step 2 understands. Run that task from the open file to see the errors in your editor's Problems list. Note that the task pushes without --activate.
To confirm the result in the product, open the script under Setup → Process Studio → Scripts and check its Versions tab. The new version is marked Compiled and is the active one.
Step 7 — Test it against a record
xmatix scripts run xmatix/automation/scripts/Account/MyValidation.csx --record <record-id>
The CLI reads the script id from the .meta.json file. It takes the entity and lifecycle phase from the script's first binding, or BeforeSave when the binding has no phase. It prints an "Invoking …" line with the script, entity, phase, change kind and record, then the server's result as JSON. Use --entity, --phase, --action and --change-kind to test a different trigger. Scripts in the CLI lists the options.
The test runs the script's active version. If you pushed without --activate, you are testing the old version. The test doesn't save the record you named, but everything the script itself does is real: records it creates or updates are saved and messages it sends go out. Use a record you can afford to change.
Step 8 — Watch the run
In a second terminal, run:
xmatix runs tail --follow
The feed prints "Tailing runs (Ctrl+C to stop)…" and adds each new run as it appears, checking every 3 seconds (--interval changes this). Every test run is recorded, so the run from Step 7 appears in the feed. Match it to your script and check its status: Succeeded, Failed or Cancelled. A validation script that blocks the save shows Cancelled with its validation failures. For the full record of one run, use xmatix runs tail --detail <run-id>. Press Ctrl+C to stop. Afterwards, check the test record and undo anything the script changed that you don't want to keep.
Expected result
xmatix --versionandxmatix --helpwork from any folder.- The repository holds a
.xmatix/workspace with no tokens in it, and a committedxmatix/tree. xmatix doctorshows ✓ for workspace, config, authority, clientId, scopes and token. The api line fails with a 404 until a later CLI release.- Your script has a new active version, and its test run is in the run feed.
Example
A developer on an implementation team keeps a tenant's automation in git. The tenant has one script, AccountCreditCheck, bound to the Account entity.
- They install the tool and run
xmatix initin a new repository calledtenant-config. - They run
xmatix loginwith the four values from their administrator. The CLI prints Workspace…/tenant-configand Signed in as with their user name. xmatix doctorshows ✓ for everything except scopes and api. They setscopestohttps://<api-host>/.defaultand run doctor again. Only api fails now, with the expected 404.xmatix scripts listprints "1 script(s)."- They run
snapshot export --skip scripts,dashboards,reportsand thenscripts pull --all, which prints "Pulled xmatix/automation/scripts/Account/AccountCreditCheck.csx (v4)". They check the metadata file for endpoint addresses and commit. - They raise the credit threshold in the
.csxfile. Then they runxmatix scripts push xmatix/automation/scripts/Account/AccountCreditCheck.csx --activate -m "raise threshold". The CLI prints "Created v5 (compileOk=yes) [activated]". - They run
xmatix scripts runon the same file with the id of a test account. In the second terminal,runs tail --followshows a new Succeeded run for AccountCreditCheck. - They commit the changed
.csxand.meta.jsonfiles. The commit history now matches the version history on the script's Versions tab.
Training
Practice exercise
In a sandbox tenant, with a script your trainer has created for you:
- Install the CLI, create a workspace in an empty git repository and sign in.
- Run
xmatix doctorand explain each line that fails. Then clear the scopes failure. - Pull all scripts. Make an edit that doesn't compile and push it with
--activate. - Fix the edit and push it again with
--activate. - Test the script against a sandbox record and find the run with
runs tail.
Expected result: Step 3 exits with code 3, and the Versions tab shows a version marked Errors that isn't active. Step 4 prints "[activated]", and a new version marked Compiled is active. The run from Step 5 shows in the feed with your script's name.
Quick reference
- Run
initin the repository root before your firstlogin. - After
login, check that Workspace is the repository and API is your organization's. doctor's api check fails with a 404 in this release. Read the token line instead.- Set
scopesto<api-url>/.defaultto clear doctor's scopes check. - Export with
--skip scripts,dashboards,reports, then runscripts pull --all. - The metadata file is a full pack. Don't push it back without reading the metadata page.
- A push creates a version. Only
--activatewith a clean compile makes it run. - Exit code 3 means it didn't compile, and 2 means someone changed the script on the server.
scripts runtests the active version, and its side effects are real.
Permissions
The CLI has no permissions of its own. Each command needs the capability that the matching setup screen needs, granted through your security profile (see the security model):
| Commands | Capability |
|---|---|
scripts list, pull, push, run, logs, and runs tail | The scripts capability, setup.automation.scripts.manage |
metadata pull and the metadata step of snapshot export | Manage metadata packages, setup.metadata.packages.manage |
rules commands and the rules step of snapshot export | The business-rules capability, setup.automation.businessrules.manage |
Without the capability, the server refuses the call with HTTP 403. The CLI prints the failure, and snapshot export counts that step as failed. init, login and doctor need no capability.
Configuration
The workspace settings are in .xmatix/config.json. login writes them, and you can also edit the file by hand:
| Setting | What it holds |
|---|---|
tenant | The tenant slug. It also names the token cache folder in your home folder. |
apiBaseUrl | The API every command calls. This decides which organization you act on. |
authority | The sign-in authority URL. |
clientId | The client id registered for the CLI. |
scopes | Space-separated sign-in scopes. When empty, the CLI uses <apiBaseUrl>/.default. |
apiVersion | The version part of API addresses. init sets v1. |
To point a workspace at a different tenant, run xmatix login again with the new values. Each value you pass replaces the saved one. Authentication covers changing settings and signing out with xmatix logout. Workspace layout lists what each command writes and what to commit.
Common problems
login says "Missing config."
On a first sign-in you must pass all four values: --tenant, --api-base-url, --authority and --client-id. Once they are saved, plain xmatix login works.
Commands say the workspace config is missing in my home folder
The message is "Workspace exists but <home>/.xmatix/config.json is missing or unreadable." Your home folder has a .xmatix folder because the token cache lives there. So a command run outside a repository finds your home folder as the workspace. Move into the repository and run the command again. If login already wrote a config.json to your home folder, see Workspace layout.
doctor says "no .xmatix/ directory found from cwd"
You are not inside a workspace, and doctor stops at the first check. Run xmatix init in the repository root, or move into a folder inside the repository.
doctor always ends in "problem(s) detected"
The api check fails with a 404 on every setup in this release, and scopes fails while scopes is empty. Clear scopes as shown in Step 4. Then judge the setup by the token line and by xmatix scripts list.
doctor says the token "could not acquire silently"
You haven't signed in from this machine for this tenant, the cached sign-in has expired, or the keyring is locked. Run xmatix login again. On Linux, check that your keyring is running and unlocked.
The export ends "finished with 1 failure(s)"
You ran it without skipping scripts, and the scripts step always fails in this release. Add --skip scripts,dashboards,reports and run xmatix scripts pull --all separately. A step that fails with 403 means you lack that kind's capability.
Push says "No sibling .meta.json next to …"
Push needs the .meta.json file that scripts pull writes next to each script. Pull the script, copy your change into the pulled file and push that file.
scripts run says "Could not infer entity name; pass --entity."
The script has no binding, so the CLI can't tell which entity to test against. Add --entity <EntityName>, for example --entity Account, or add a binding to the script in the product.
I pushed, but the old behaviour still runs
The push had no --activate, or the new version didn't compile (exit code 3). Push again with --activate after fixing any errors, or activate the version on the script's Versions tab.
Common questions
What should the first commit contain?
Commit the xmatix/ tree, plus .xmatix/config.json, .xmatix/.gitignore and .vscode/tasks.json. The config file holds connection values only, so a teammate who clones the repository just runs xmatix login. Tokens live in each person's home folder and never reach the repository. Before you commit, check the metadata file for endpoint addresses you don't want to share. Remember that it is a full pack, which is safe to review but not safe to push back without the steps on the metadata page.
How do teammates join an existing workspace?
They clone the repository, install the tool and run xmatix login in the repository. The saved config supplies everything except their own sign-in. Then they run xmatix doctor and xmatix scripts list. Each person signs in as themselves, and the CLI acts with that person's permissions, so there is no shared credential to look after. Someone who lacks a capability gets HTTP 403 for that kind of artifact.
Should I use xmatix watch while I learn?
Not at first. watch runs scripts push on every .csx file you save under xmatix/automation/scripts/, never with --activate. Each save creates a new version on the server. The versions don't run, but they fill the Versions tab. Push by hand until you know the loop, then use watch on a branch where frequent pushes are expected.
Is scripts run a dry run?
No. It doesn't save the record you name, but it runs the script's active version for real, so any record the script writes is saved and any message it sends goes out. Test against a record you can afford to change, and check it afterwards.
