Command line
The penstock command does in a terminal what the editors do, with the same settings and the same answers, so it works in a script or a pipeline.
Install it
npm install -g @kern0x1b/penstock-cli
The package is on npm. It needs Node.js 22.22.2 or later in 22, 24.15.0 or later in 24, or 26 and later. You can also run it without installing, as below.
Two ways to run it
1. Once, with npx
npx @kern0x1b/penstock-cli check .
npx @kern0x1b/penstock-cli doctor
It downloads the command the first time and asks the npm registry each time you do not pin a version.
2. Pinned by your project, with the wrapper
The wrapper is a small script, like gradlew, that runs the version your project chooses. Everyone, and your pipeline, runs the same version.
- In your project run
npx @kern0x1b/penstock-cli init. - Penstock writes three files:
penstockw,penstockw.cmd(for Windows) andpenstock/wrapper/penstock-wrapper.properties. It also writespenstock.yamlif you have none. See penstock.yaml. - Commit all three wrapper files.
- From now on run
./penstockw check .. The first run downloads the pinned version into~/.penstock/wrapper/dists. Every later run starts from there, offline.
./penstockw check .
./penstockw update # pin the latest version
./penstockw update 26.9.0 # pin a version you choose
update pins the version, downloads it, and replaces the wrapper scripts with the ones that version ships. You can also edit version= in the properties file by hand. A company registry or a tarball goes in distribution= in the same file.
The wrapper needs Node.js 22.22 or later, with npm, on the PATH. Without them it says penstockw needs Node.js 22.22 or later, with npm, on the PATH and stops with the exit code 127.
The properties file holds two lines. version= is the version to run, or latest to ask npm each time. distribution= is optional: a registry spec or a tarball, and a path that starts with ./ or ../ is taken from the folder of the wrapper. Set PENSTOCK_HOME to keep the downloads somewhere other than ~/.penstock. There is no command called wrapper: that was the old name of update, and it still works and says so. penstockw.cmd is the same script for Windows.
Paths and configuration
A path defaults to the current folder. Penstock reads penstock.yaml from there upward, so it does not matter which folder you run it in. Like Maven with a pom.xml.
What you get
| You want to | Run |
|---|---|
| Set up a project | penstock init |
| Try an example | penstock init --example camunda-8 |
| Find out why something does not work | penstock doctor |
| Let a project run its hooks | penstock trust |
| Write element templates from your workers | penstock templates generate |
| Check the diagrams | penstock check . |
| Deploy | penstock deploy . --wait |
| See what changed | penstock diff main |
| Get pictures | penstock export . --out docs/img |
| Share a diagram as one file | penstock share process.bpmn |
| Import from draw.io or Visio | penstock import diagram.drawio |
| Plan the move to Camunda 8 | penstock migrate . |
| Run scenarios | penstock scenarios run . |
| Let an AI assistant use the diagrams | penstock mcp --config |
| Set up a pipeline | penstock init --ci github |
| See which licence this machine has | penstock license |
| Pin the version for the project | ./penstockw update |
Every command, with every option, an example, what it needs and its exit codes, is in Every command. Pipelines and the pull request bot are in Pipelines, reports and the bot.
Paid commands
A command marked Pro, Team in a pipeline is a paid one. One rule decides what it needs: Pro on your machine, Team in a pipeline. A pipeline is any run where CI is set. When you run a paid command without the licence, it prints what the feature gives and how to buy or sign in, and exits with 1. See Plans and licence.
The licence
Every machine starts with 30 days of Pro. Run penstock license to see where yours stands, penstock license buy to buy Pro (or buy team), and penstock license login to sign in on another machine. The licence is the file ~/.penstock/license.json, shared with the editors. See license.
Exit codes
0 | All is well. |
1 | The command found errors, was refused for want of a licence, or failed at what it was asked to do. |
2 | The command itself crashed. The message goes to the error output. |
130 | You pressed Ctrl+C twice while scenarios run was running. Once asks the engine to stop and keeps going. |
Output and streams
An answer goes to standard output, whatever it says and whatever the exit code is. penstock check > findings.txt keeps the findings even when it exits with 1. A refusal goes to standard error and nothing goes to standard output: a missing path, a file that will not parse, a value an option does not take, a licence message, a hook that stopped the stage. The help and the version are answers, and an unknown command is a refusal.
Machine output
--format json gives JSON. --format sarif gives SARIF 2.1.0, which GitHub code scanning reads. --format github gives annotation lines for a workflow. Colour is used only in a terminal.
Old names
Older names still work in this release and say what replaces them: lint and analyze are check --only rules and check --only flow. against is diff <ref>. config and profiles are doctor. upgrade, login and logout are license buy, license login and license logout. wrapper is update. The flags --json and --image are --format json and --images.
Common problems
- "No .bpmn files found."
- The path has no diagram. Check the path, or run from your project folder.
- "penstockw needs Node.js 22.22 or later".
- Install Node.js 22.22 or later, and make sure
nodeandnpmare on the PATH of the shell or the CI job. - "penstockw could not find the latest @kern0x1b/penstock-cli".
- The npm registry could not be reached. Pin a version in
penstock-wrapper.properties. - The command says a feature is part of Pro, in a pipeline.
- A pipeline needs Team. Give the pipeline a Team key in
PENSTOCK_LICENSE. See Buying and signing in. - Unknown command.
- Run
penstock helpfor the list.