Reference
Commands
ocelkit dev, ocelkit check, and ocelkit describe: what each one prints, and how to read it.
ocelkit has three commands:
ocelkit devopens the map in your browser, and redraws it when you save a process file.ocelkit checkcompares your process files with your data, and prints what it finds.ocelkit describeprints the event types and object types in your data.
Each one reads ocelkit.config.ts, so run them from the folder it's in. The examples on this page use the Order Management log from the quickstart.
Open the map
$ npx ocelkit devStarts the workspace and opens it in your browser:
Workspace: http://localhost:4747The map reloads when a process file changes. Press Ctrl+C to stop.Leave it running while you work. Each time you save a process file, the map redraws. Reading the map shows what's on it.
The workspace runs on your machine, and only your machine can open it.
ocelkit reads your config file and your log once, when it starts. If you change either, stop the command and start it again.
Use another port
The workspace uses port 4747. If another program has that port, ocelkit takes the next free one, up to 4766, and tells you:
Port 4747 is in use, so the workspace uses port 4748.Workspace: http://localhost:4748The map reloads when a process file changes. Press Ctrl+C to stop.Add --port to choose the port yourself:
$ npx ocelkit dev --port 4800With --port, ocelkit uses that port or none. If it's taken, the command stops:
Port 4800 is in use. Stop the program that uses it, or choose another port with --port.Keep the browser closed
Add --no-open to start the workspace without opening a browser tab. That's useful when the tab is already open, or when your agent starts the workspace for you.
$ npx ocelkit dev --no-openCheck your files
$ npx ocelkit checkCompares every process file with your data: each event type, each object type, and each pair of a flow. The workspace doesn't have to be running.
When nothing is wrong, it says so:
processes/payments.ts no problems0 errors, 0 warningsRead the output
Here's a project with three process files, each with something to report:
processes/confirmed.ts warn flows.orders[1] No "pick item" event links to an object of type "orders".processes/orders.ts info flows.items 66 objects of type "items" have equal timestamps. All 66 unmodeled occurrences are only possible.processes/payments.ts error activities.payOrder "pay ordr" is not an event type in the data. Closest: "pay order".1 error, 1 warningEach file has its own block, and each line of a block has three parts:
- The level:
error,warnorinfo. - The place in the file, as you'd write it in TypeScript.
activities.payOrderis thepayOrderkey ofactivities.flows.orders[1]is the second pair of theordersflow, since the pairs are counted from 0. - The message, with the fix when it's clear. The error above names the closest event type in your data,
pay order.
The level tells you what to do:
- An error stops the file. A name isn't in your data, or the file can't be read. The file has no map until you fix it.
- A warning doesn't. The file works, but part of it probably isn't what you meant. Here, no pick item event is attached to an order, so that pair can never happen. The map opens, with the warning above it.
- An info line is a fact about your data. There's nothing to fix. Here, 66 items have events at the same time, so ocelkit can't tell which came first, and counts the moves that depend on it as possible. Reading the map shows how the map draws them.
The last line counts the errors and the warnings of all your files.
Use the exit code
ocelkit check exits with code 0 when every file can be used. It exits with code 1 when a file has an error, or when it finds no process files. Warnings and info lines don't change the code.
That's what lets the check fail a CI job, or tell your agent to try again.
Give the result to your agent
Add --json to print the same result as JSON:
$ npx ocelkit check --jsonHere's the payments file with its typo:
[ { "name": "payments", "path": "processes/payments.ts", "result": { "_tag": "Rejected", "errors": [ { "_tag": "UnknownEventType", "at": [ "activities", "payOrder" ], "name": "pay ordr", "closest": "pay order" } ], "warnings": [], "pairs": [] }, "infos": [] }]The output has one entry for each process file:
nameandpathare the process and its file.result._tagsays how the check went.Acceptedmeans the file can be used.Rejectedmeans it has errors.Unreadablemeans ocelkit couldn't read the file, andreasonsays why.errorsandwarningslist the problems. Each has a_tagfor the kind of problem, the place in the file asat, and the values of its message, such asclosest.infoslists the facts about your data, in the same form.- An accepted file has
processin place oferrors: its activities and its pairs, as ocelkit read them. A rejected file keeps thepairsof the flows that have no error.
The exit code is the same with and without --json.
Learn what each message means, and how to run the check in CI and from your agent, in Checking your files.
See what's in your data
$ npx ocelkit describePrints every event type and object type in your log, with the number of its events or objects. It doesn't read your process files, so you can run it before you write the first one.
Event types confirm order 2000 create package 1128 failed delivery 311 item out of stock 1544 package delivered 1128 pay order 2000 payment reminder 566 pick item 7659 place order 2000 reorder item 1544 send package 1128Object types customers 15 employees 18 items 7659 orders 2000 packages 1128 products 20These are the names a process file uses. An activity names an event type, and a flow names an object type, each spelled exactly as it is here.
See which events involve which objects
An event can involve more than one object: placing an order involves the order, the customer, and every item in it. Add --links to see which object types the events of each type are attached to:
$ npx ocelkit describe --linksIt prints the same lists, then this:
Links: how many events of each type are attached to each object type confirm order customers 2000, employees 2000, items 2000, orders 2000, products 2000 create package employees 1128, items 1128, packages 1128, products 1128 failed delivery employees 311, items 311, packages 311, products 311 item out of stock employees 1544, items 1544, products 1544 package delivered employees 1128, items 1128, packages 1128, products 1128 pay order items 2000, orders 2000, products 2000 payment reminder items 566, orders 566, products 566 pick item employees 7659, items 7659, products 7659 place order customers 2000, items 2000, orders 2000, products 2000 reorder item employees 1544, items 1544, products 1544 send package employees 1128, items 1128, packages 1128, products 1128Each line is one event type. Read the pay order line as: 2,000 pay order events are attached to an item, 2,000 to an order, and 2,000 to a product.
So each number answers one question: how many events of this event type are attached to this object type?
To see how an event is counted, here's one place order event from the log, with its objects:
| Object type | Its objects in this event | Adds |
|---|---|---|
| customers | AlpenTech Innovations AG | +1 |
| items | i-880001i-880002i-880003 | +1 |
| orders | o-990001 | +1 |
| products | EchoiPhone 11 Pro | +1 |
This event is attached to seven objects of four types, so it adds 1 to each of the four numbers on the place order line. It has three items, and it still adds 1 for items, not 3. A number counts events, not objects.
Each number is counted on its own, so one event is counted in several of them. That's why you can't add the numbers of a line together: place order has 2,000 events, not 8,000.
Here's what to make of a line:
- An object type on the line can have that activity in its flow. Pay order events are attached to orders, so pay order can be a step in the
ordersflow. - An object type that's missing can't. No pick item event is attached to an order. Put pick item in the
ordersflow, and the check warns you that the pair can never happen. - A number smaller than the event type's own count means only some of its events are attached to that object type. In this log, every number matches. In the Container Logistics log, another public sample, 594 events are Book Vehicles, and 574 of them are attached to a vehicle. The other 20 have none.
Give the types to your agent
Add --json to print the result as JSON, with or without --links:
$ npx ocelkit describe --links --json{ "eventTypes": [ { "type": "confirm order", "events": 2000 }, … ], "objectTypes": [ { "type": "customers", "objects": 15 }, … ], "links": [ { "eventType": "confirm order", "objectType": "customers", "events": 2000 }, … ]}eventTypeshas each event type and the number of itsevents.objectTypeshas each object type and the number of itsobjects.linksis there only with--links. It has one entry for each number of the links section: an event type, an object type, and the number ofevents.
Each list is sorted by name. An agent that reads this before it writes a process file knows the exact names in your data, and which activities fit which flow.
When a command can't start
Every command reads your config file and your log first. If it can't, it says what's missing and exits with code 1.
When there's no config file in the folder:
/Users/you/shop/ocelkit.config.ts does not exist. Run ocelkit in the folder of ocelkit.config.ts.ocelkit doesn't look for the config in the folders above, so move to its folder and run the command again.
When the log isn't where the config says:
The data file /Users/you/shop/data/orders.sqlite does not exist.The path comes from data in your config file, and it's relative to that file.
ocelkit check also reads your processes folder:
The process folder /Users/you/shop/processes cannot be read. The folder does not exist.The path comes from processes in your config file.
Help and version
Add --help to a command to see its flags:
$ npx ocelkit check --helpocelkit --help lists the commands, and ocelkit --version prints the version you have installed.