# heddle-devtools
Workspace-internal tooling. Not published to crates.io.
## Commands
- `heddle-devtools grpc-ts [--check]` — regenerate (or audit) the
TypeScript protobuf and Connect client package for the gRPC service.
With `--check` the tool generates into a tempdir and diffs against
the checked-in output; used as a CI gate. Without it, writes to
`clients/grpc/src/gen/` and syncs `clients/grpc/package.json` to the
`heddle-grpc` crate version.
- `heddle-devtools audit-idempotency` — fail if any state-changing
RPC's request message is missing `string client_operation_id = 15`.
- `heddle-devtools audit-coverage <lcov> --gate <crate>=<pct> ...` —
parse `lcov.info` and fail if any gated crate falls below its
per-crate line-coverage threshold.
- `heddle-devtools check-no-silent-default-tree-load` — repo-wide
audit that no code path silently loads the default working tree
(see the source for the full rule).
## Single-source proto contract
There is **exactly one** copy of `service.proto` in this workspace:
```
crates/grpc/proto/heddle/v1/service.proto
```
Every consumer reads from that path:
- `crates/grpc/build.rs` — tonic-prost codegen for the Rust server
and client.
- `crates/devtools/src/main.rs::run_grpc_ts` — TypeScript protobuf
and Connect client package (consumed by tapestry).
- `crates/devtools/src/main.rs::run_audit_idempotency` — proto-side
idempotency lint.
- `crates/cli/tests/idempotency_lint.rs` — server-side dedup lint.
This file lives inside `crates/grpc/` so the crate's published tarball
contains everything `cargo build` needs from a fresh download. Do not
re-introduce mirror copies under `proto/` or elsewhere; the historical
mirrors drifted (missing `RedactionTransfer` before heddle#63 r1)
because nothing audited the duplication. The regression test
`heddle-devtools::tests_proto_single_source::only_canonical_proto_exists`
pins the contract.