Penstock

Guide / Test and run

Code links

Code links tie your diagrams to the code that runs them, so you can jump between a task and its worker, and find out when they disagree.

Pro Team in a pipeline. Going from a Camunda 7 delegate to its class is free.

What it is

A diagram says "this task needs the job type charge-card". Your code has a worker for charge-card. Code links know both, and connect them. They read Java, Kotlin, Groovy, Scala, JavaScript, TypeScript, Python, Go and C# by reading the text, so a worker in another language or another repository still counts.

Free and Pro

Going from a Camunda 7 task to its Java class or Spring bean is free. See Editing a diagram. Everything below needs Pro, and Team in a pipeline. Without Pro, Penstock keeps only class and bean links, and an action that needs the rest says what it gives and offers to buy or sign in.

The Code tab

The Code tab of the sidebar shows the code behind the selected step: the workers, classes, beans, tests and usages that name it, with Go to code, Find usages, Run tests and Debug tests on the head of the tab. A group with more than a handful of entries opens in a view of its own, with a ‹ back. With nothing selected the tab says Select a task to see its code, and a step nothing in the project runs, tests or uses is said plainly rather than left as an empty tab.

The Code tab of the sidebar showing the worker that runs a selected task, with Go to code and Find usages and a Runs in list holding one entry
A service task is selected. The tab names the worker that runs it under Runs in, with Go to code and Find usages above it.

Where you use the links

JetBrains

All of it works in the IDE, in Java and Kotlin sources: click through, completion, gutter icons, Code Vision, Find Usages and the debugger's position on the diagram. Ctrl/Cmd+click opens a diagram element named in a string or a comment, and the Run tests and Debug tests actions on the Code tab run the test cases that use the selected step. See Code links in the IDE.

VS Code

In VS Code, with Pro, they work in the nine languages the command line reads. A code lens above a worker, delegate or subscription names the diagram and element that use it. Go to Definition and Find All References go between code and diagrams, the Penstock view in the Activity Bar lists processes, workers, variables, messages, errors, and element templates, and the Problems view carries what penstock code and diagram checks report. Renaming with F2 updates diagrams and code in one step, and stopping in a worker marks the diagram step in Java debug sessions. Running tests from a diagram opens the test at the cursor. Gutter icons are not in VS Code. See Code links in VS Code.

Command line

Only the check against the code: penstock code. The MCP tool check_code_links does the same for an AI assistant.

What is linked

Check the diagram against the code

Penstock compares every diagram with the code and reports what does not fit. In the editor, the Problems tab has a Code group, and the check card lists the same findings.

Check diagrams against code in your tool

JetBrains

The check card has a Code section. For the whole project, right-click in the Penstock tool window and choose Run Penstock | Code. Each finding has a file and line, which the IDE opens at the line.

VS Code

The check card has a Code section. In VS Code the same findings are in the Problems view for the whole workspace, under the source penstock, once you have Pro. Each one has a file and a line, and a click opens it. For a pipeline, run penstock code. See Code links in VS Code.

Command line

$ penstock code .
3 source file(s), 1 diagram(s), 4 reference(s) from diagrams to code

Every task the diagrams hand to code has something in the code to run it.

Each finding has a file and a line. --format json is for a tool. See Every command.

The Problems tab reading 2 errors. Under the group Code, the finding lineItems is read, but only lineItem is set, on Screen each line item. Under Rules, the finding that the element of type loop characteristics must have property outputElement, compat/loop-characteristics
A Code group in the Problems tab: a variable the step reads under a name that is only set under another.
It reports:
FindingRule
Nothing in the code runs a stepcode/missing-implementation
No worker handles a job typecode/no-worker
No external task worker subscribes to a topiccode/no-topic-worker
A class named in the diagram is not in the projectcode/class-missing
No Spring bean has the name a diagram usescode/bean-missing
A call activity calls a process no diagram definescode/unknown-process
A business rule task calls a decision no file definescode/unknown-decision
A user task shows a form no file definescode/unknown-form
A worker for a job type no diagram usescode/unused-worker
A variable is read, but only a similar one is setcode/variable-typo
Nothing throws the error a step catchescode/never-thrown

Names are matched exactly. A name that differs only by case, such as charge-Card against charge-card, is pointed out, because Camunda matches names exactly. Connector job types such as io.camunda:http-json:1 and job types set by an expression are understood and left alone. Job types of Camunda 8 execution and task listeners count as workers. The full list is in Every rule.

Where a step and its code do not agree

These findings are reported on the step. The three about variables, the first three in the table, are marked in the code too, on the line that reads or writes the variable.

FindingId
A worker reads a variable it does not fetch, so it is null at runtimecode/worker-fetch
A worker sets a variable that no step after it readscode/writer-unread
A parallel multi-instance step collects results with no output element, so every instance overwrites the otherscode/lost-update
A worker reads a variable that no step before it setscode/late-read
A job type, topic, class or bean is one letter off the one in the code, or differs from it only in casecode/near-name
A mapping line reads a value that an earlier line was meant to set, which the engine gives as null (camunda#11789)code/mapping-order
A job worker takes its job type from its method name, so a rename breaks the diagram silentlycode/implicit-job-type

The debugger position on the diagram

When a debugger stops in the code of a step, the diagram shows where the process is. The step that the code belongs to is outlined and carries a badge, Paused here, and the canvas scrolls to it, into the sub-process if that is where it is. When the debugger runs on or stops, the marks go.

Penstock finds the step in two ways:

It is a Pro part of the code links, and it needs the diagram and the code to be indexed. Nothing is written to a file and nothing is changed in the program being debugged: the questions it asks are reads of the values in the paused frame.

The debugger position in your tool

JetBrains

Debug your application as you do now and stop in a worker, a delegate or a listener. The step is marked in the editor of the diagram that holds it. It reads Java and Kotlin code, and needs Pro. While the IDE is still indexing, nothing is marked. See Code links in the IDE.

VS Code

Debug your application as you do now and stop in a worker, a delegate or a listener. The step is marked in the editor of the diagram that holds it. It tracks Java debug sessions and marks the diagram step the stopped worker runs. Pro. Debugger tracking for languages other than Java is not covered. See Code links in VS Code.

Command line

Not available on the command line. A debugger position needs an editor with a diagram open.

Rename a name the diagram and the code share

A job type, a topic, a Camunda 7 bean or class, and a process, decision or form id are written in the diagram and in the code. Renaming one from either side opens a preview that lists every diagram, decision, form and source file that writes the name, in the project and in a linked repository, and one command writes them all. Going the other way, changing such a value in the properties panel offers to rename the places that still hold the old one. It never edits code on its own. A process id, a job type and a message name are what a deployed engine knows, so the preview says that instances already running keep the old name, and offers to ask the engine, only when you ask, how many are active. Variables are left out, because the analysis reports the uses it saw, not that it saw them all. See Rename.

Element templates from worker code

A job worker in your code can become an element template. Create Element Template, on a @JobWorker method, a newWorker().jobType(...) registration or a Camunda 7 external task subscription, writes the template of that job type or topic into .camunda/element-templates, with one field for each variable the worker reads, typed by its Java type, an enum as a dropdown, and the variables it sets as output mappings. A template that already exists for the same job type is brought up to date, with its version raised and the labels and descriptions you wrote kept. A template that no longer matches its worker is marked, and the gap is named on the step. See Element templates.

Other repositories

If your workers live in another repository, name it in penstock.yaml:

linked:
  - ../order-workers
  - ../shared-delegates

Paths are relative to the project root. Their diagrams, workers, delegates and beans are read with this project's. A path that is not checked out is skipped. The code check reads them too.

What you see

Common problems

No links appear.
Code links need Pro. Without it, the project model shows a Code line that offers to buy or sign in.
A worker in another repository is reported as missing.
Add that repository to linked in penstock.yaml.
A worker I know exists is not found.
Penstock reads the text of Java, Kotlin, Groovy, Scala, Python, JavaScript, TypeScript, Go and C# files. It skips node_modules, build, target, out, dist and .git. Generated code in those folders is not read.