Penstock

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.

Free Node.js 22.22.2 or later in 22, 24.15.0 or later in 24, or 26 and later. Some commands need Pro, and Team in 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.

  1. In your project run npx @kern0x1b/penstock-cli init.
  2. Penstock writes three files: penstockw, penstockw.cmd (for Windows) and penstock/wrapper/penstock-wrapper.properties. It also writes penstock.yaml if you have none. See penstock.yaml.
  3. Commit all three wrapper files.
  4. 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 toRun
Set up a projectpenstock init
Try an examplepenstock init --example camunda-8
Find out why something does not workpenstock doctor
Let a project run its hookspenstock trust
Write element templates from your workerspenstock templates generate
Check the diagramspenstock check .
Deploypenstock deploy . --wait
See what changedpenstock diff main
Get picturespenstock export . --out docs/img
Share a diagram as one filepenstock share process.bpmn
Import from draw.io or Visiopenstock import diagram.drawio
Plan the move to Camunda 8penstock migrate .
Run scenariospenstock scenarios run .
Let an AI assistant use the diagramspenstock mcp --config
Set up a pipelinepenstock init --ci github
See which licence this machine haspenstock 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.

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

0All is well.
1The command found errors, was refused for want of a licence, or failed at what it was asked to do.
2The command itself crashed. The message goes to the error output.
130You 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 node and npm are 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 help for the list.