This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is not a single top-level workspace. Run all build/test commands from within the relevant component directory.
| Directory | Description |
|---|---|
proto/ |
Shared gRPC contract files (plugin.proto v1, plugin_v2.proto v2) |
drivers/rust/ |
Rust plugin driver (3 crates: driver/, driver_ffi/, driver_pact_tests/) |
drivers/jvm/ |
JVM (Kotlin) plugin driver |
cli/ |
Rust binary for plugin lifecycle management (install, list, enable, disable, remove, env) |
plugins/csv/ |
Reference CSV content-matcher plugin (Rust) |
plugins/protobuf/ |
Reference Protobuf content-matcher plugin (JVM/Kotlin) |
examples/ |
Cross-language integration tests (csv, protobuf, gRPC) |
repository/repository.index |
Checked-in plugin registry index — treat as source data, not generated output |
protocmust be installed for Rust driver, CLI, JVM builds, and example/plugin builds.- Integration tests require plugins installed in
~/.pact/plugins(orPACT_PLUGIN_DIR). Install with:scripts/install-plugin-cli.sh ~/.pact/bin/pact-plugin-cli -y install protobuf ~/.pact/bin/pact-plugin-cli -y install csv
- Set
pact_do_not_track=trueto suppress plugin telemetry in local runs.
cargo build
cargo test
cargo test <test_name> # single test
cargo clippy --all-targets --all-featurescargo build
cargo test
cargo test --test cli-tests cli_tests # integration-style CLI snapshot test
cargo test <test_name> # single unit test# drivers/rust/driver_ffi/
cargo test <test_name>
# drivers/rust/driver_pact_tests/
cargo test <test_name>./gradlew -s --no-daemon -i publishToMavenLocal
./gradlew -s --no-daemon -i check
./gradlew detekt
./gradlew :core:test --tests 'io.pact.plugins.jvm.core.DriverPactTest' # single testcargo build --release
cargo test <test_name>./gradlew installDist
./gradlew installLocal # unpacks into ~/.pact/plugins/protobuf-<version>
./gradlew test --tests '<fully-qualified test name>'- CSV:
./gradlew checkinexamples/csv/csv-consumer-jvm,cargo testinexamples/csv/csv-consumer-rust, build provider, then verify with~/.pact/bin/pact_verifier_cli. - Protobuf:
./gradlew checkinexamples/protobuf/protobuf-consumer-jvm,cargo testinexamples/protobuf/protobuf-consumer-rust, build/run Go provider, then verify with~/.pact/bin/pact_verifier_cli. - gRPC:
scripts/run-grpc-examples.shdrivesexamples/gRPC/area_calculator.
Plugins communicate with drivers via gRPC using the shared contract in proto/plugin.proto (v1) and proto/plugin_v2.proto (v2, adds capability negotiation via hostCapabilities in InitPluginRequest). On startup, a plugin must print a JSON payload to stdout with port and optional serverKey; the driver reads this before any gRPC calls.
Both drivers do: find installed plugins → load pact-plugin.json manifest → start plugin as a child process → read startup JSON from stdout → send InitPluginRequest → register catalogue entries. The feature catalogue is the key shared abstraction: entries typed as CONTENT_MATCHER, CONTENT_GENERATOR, TRANSPORT, MATCHER, or INTERACTION.
The Rust driver stores generated protobuf bindings checked-in at drivers/rust/driver/src/proto.rs and proto_v2.rs. build.rs only regenerates them when PACT_PLUGIN_BUILD_PROTOBUFS is set — proto changes require an explicit regeneration step.
The JVM driver is mixed-language: production code is Kotlin under drivers/jvm/core/src/main/kotlin, tests are Groovy/Spock specs under drivers/jvm/core/src/test/groovy.
Part of the runtime contract, not just packaging metadata. Keep entryPoint (and optional OS-specific entryPoints) in sync with the actual executable layout. The Protobuf plugin demonstrates OS-specific entry points plus a JVM runtime dependency.
Each installed version lives in $HOME/.pact/plugins/<name>-<version>/ containing pact-plugin.json. Override the root with PACT_PLUGIN_DIR.
cli/ manages plugin lifecycle; installation-by-name is driven by repository/repository.index. When changing installation logic or repository metadata handling, update both the CLI code and the index file.
- Rust formatting uses 2-space indentation (
rustfmt.toml). - Keep
lib.rs/main.rsthin; most logic lives in focused modules. - Use
anyhowfor error context propagation; avoidunwrap()/panic in library code. - Existing ecosystem choices:
serdefor serialization,tokiofor async,tracing/logfor diagnostics. - Derive
Debug,Clone,Default,PartialEqwhere it improves ergonomics and matches surrounding code. - Unit tests go in
mod testsblocks; cross-module behavior tests go intests/. - Finish Rust changes with
cargo testandcargo clippy --all-targets --all-features.