Skip to content
pb-diff Help

Automate with pb-diff-cli

Everything the desktop application opens is a window for a person. When there must not be one, as in a build step, a CI job, a pre-commit hook or an AI coding agent, use pb-diff-cli.exe, installed beside pb-diff.exe. It never creates a window, never prompts and never reads standard input, writes its result to standard output, and reports the outcome as an exit code. It needs no PowerBuilder and reads no machine settings, so the same command line gives the same bytes on every machine.

pb-diff-cli list        ui.pbl --format json
pb-diff-cli export      "ui.pbl!*.srw" --out-dir .\windows
pb-diff-cli compare     old\w_main.srw new\w_main.srw --format json
pb-diff-cli compare-lib old.pbl new.pbl --changed-only --format json
pb-diff-cli merge3      mine.srw base.srw theirs.srw --output merged.srw --format json
pb-diff-cli report      changes old\w_main.srw new\w_main.srw --output review.html --format json
pb-diff-cli check       src\ws_objects --format json

On a build machine, use pb-diff-ci.exe instead: it needs no licence and no network, and has the commands that stay at the level of the object. See Run pb-diff in CI.

Two rules

Pass --format json to every command. Text output is prose for a person and may be reworded between releases; the JSON payloads, their schemaVersion and the published schemas are the contract. --format json is the machine form of every command, report included. --report-format makes a different choice: the rendition a reader gets, which can be PDF, HTML, CSV, JSON, RTF or Markdown.

Read the exit code before the payload. The outcome is one of six codes, and a caller has to branch on the one it receives. Treating any non-zero code as a failure turns the requested answer, "these two releases differ", into a broken build.

Code Meaning
0 Success; for compares, no differences; for check, nothing noticed
1 Compares: differences found. Validate: warnings only. Check: findings
2 Invalid input, missing file or entry, or bad arguments
3 Three-way merge left conflicts
4 Internal error
5 No valid licence

Code 3 is what merge3 returns when conflicts are left, and in that case no merged file is written. Code 4 is a bug in pb-diff and is worth reporting. Code 5 means the machine running the command has no valid licence: every command but help, schema and license needs one. A CI job uses pb-diff-ci, which needs none, and a build server that needs pb-diff-cli activates its service account (see Run it on a build server or in CI).

A first gate

Run from the docs\examples\order-desk folder of the installation, this PowerShell gate lists what changed between the two library releases of the Order Desk examples, and fails only when the input was unusable. It reads the exit code first, because exit code 2 leaves standard output empty and puts the error on standard error:

$raw = pb-diff-cli compare-lib libraries/release-1.4/orders.pbl libraries/release-1.5/orders.pbl --changed-only --format json | Out-String
switch ($LASTEXITCODE) {
    0       { 'No object changed.' }
    1       { ($raw | ConvertFrom-Json).entries | ForEach-Object { '{0,-9} {1}' -f $_.status, $_.name } }
    default { throw "Comparing the libraries failed with exit code $LASTEXITCODE." }
}

It prints eleven lines, one per changed object, such as modified d_order_lines.srd. The examples folder also holds, under results, the JSON of every command this Help runs, so a script or an agent can see a real payload before it reads one of its own.

A merge without the window

pb-diff-cli merge3 applies every change only one side made and reports the rest:

pb-diff-cli merge3 mine/n_pricing.sru base/n_pricing.sru theirs/n_pricing.sru --output merged/n_pricing.sru --format json

Exit code 0 means the merge was clean and merged/n_pricing.sru was written; exit code 3 means conflicts remain, in which case nothing is written and the JSON lists each conflict with its node, the base line range and the text each side wanted. --force-partial writes anyway, taking the Base for every conflict. The merged file is exactly what Save writes in the desktop application: UTF-16LE with a byte-order mark and CRLF, or UTF-8 when the Base is a PowerBuilder 2025 Solution source. The JSON on standard output follows its own contract and is UTF-8 without a mark.

When a hook cannot show a window

Some source-control hooks and pipelines cannot show a window at all. Use the CLI there:

pb-diff-cli compare old\w_main.srw new\w_main.srw --format json

Exit code 0 means no differences, 1 means differences were found, 2 means the input was unusable. A pre-commit hook or a CI gate can branch on it directly. pb-diff.exe, by contrast, is the desktop application: a build script that calls it waits for a window nobody will close.

Agents

An AI coding agent should call pb-diff-cli.exe and follow the two rules above. The first part of the Command-Line Tool Reference, Using pb-diff-cli from a script or an AI agent, is the authoritative reference for inventorying a library, comparing two releases, gating a build with compare-lib --changed-only, and resolving and verifying a three-way merge. For instructions an agent can load directly, use skills\pb-diff\SKILL.md in the installation folder. The same limits apply to an agent as to a person: libraries remain read-only, compiled entries are not decompiled, renames must be declared, and pb-diff does not compile the object an agent writes.

The full reference

Help ▸ Command-Line Tool Reference opens the Command-Line Tool Reference: every command, its options, the addressing syntax, the payloads and the exit codes. pb-diff-cli help --format json gives the same catalogue as data, and pb-diff-cli schema prints the published schemas. pb-diff-cli help holds to the same contract as the commands it describes: an unknown command or an unknown option exits 2 and says so, whichever format was asked for, and pb-diff-cli <command> --help shows the help without running anything.