feat: add gRPC transport (agctl grpc)#46
Merged
Merged
Conversation
First-class in-tree gRPC transport — a fifth transport alongside http/kafka/db/logs. Every command emits one JSON envelope with deterministic exit codes; gRPC status is a result (ok:true, exit 0) unless an assertion fails, mirroring HTTP 4xx. - grpc: config section (targets/descriptors/templates) + pydantic models (GrpcTls/GrpcTarget/GrpcDescriptorSource/GrpcTemplate/GrpcConfig) and cross-reference validation. - GrpcClient: reflection-first/descriptor-fallback proto resolution (file_containing_symbol), JSON<->protobuf (json_format/message_factory, no generated _pb2), all four call types, healthcheck (grpc.health.v1), mTLS, lazy imports + DI seams. - gRPC assertions: validate_grpc_assertion_args + evaluate_grpc_assertions reusing the jq/subset/equals primitives + a hardcoded status map. - grpc call: template + free-form; unary/client-stream return one envelope; server-stream/bidi stream NDJSON out + consume NDJSON in (stdin), with signal-driven stop + a terminal-status summary. - grpc healthcheck; grpc-services/grpc-methods discover categories. - grpc extra (grpcio/grpcio-tools/grpcio-health-checking/grpcio-reflection/ protobuf/jq) + integration aggregate + CI install line. - Docs: DESIGN (struck from future-work; added throughout), ARCHITECTURE, sample config, consumer skill, README. Design via brainstorming -> spec -> plan -> 14 TDD tasks (each per-task reviewed) + an independent 4-reviewer fan-out code review; all Critical and Important findings fixed. Full suite + live in-process grpcio integration tests green. Spec: docs/superpowers/specs/active/2026-07-09-grpc-support-design.md Plan: docs/superpowers/plans/active/2026-07-09-grpc-support.md Co-Authored-By: Claude <noreply@anthropic.com>
HumanBean17
force-pushed
the
feat/grpc-support
branch
from
July 10, 2026 08:34
edf9fc8 to
a73ed93
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds gRPC as a first-class, in-tree transport (
agctl grpc) — a fifth transport alongside http/kafka/db/logs. Every command emits one JSON envelope with deterministic exit codes (0/1/2); gRPC status is a result (ok:true, exit 0) unless an assertion fails, mirroring HTTP 4xx.What's added
grpc:config section —targets(named endpoints, TLS/plaintext, reflection mode),descriptors(reflection fallback:.protoglobs or pre-compileddescriptor_set),templates(named calls). New pydantic modelsGrpcTls/GrpcTarget/GrpcDescriptorSource/GrpcTemplate/GrpcConfig+ cross-reference validation.GrpcClient(agctl/clients/grpc_client.py) — reflection-first/descriptor-fallback proto resolution (viafile_containing_symbol), JSON↔protobuf serialization (json_format+message_factory, no generated_pb2), all four call types (unary / server-stream / client-stream / bidi),healthcheck(grpc.health.v1). Lazy grpcio/protobuf imports + DI seams.agctl/assertions.py) — newvalidate_grpc_assertion_args/evaluate_grpc_assertionsreusing the jq/subset/equals primitives; gRPC status name↔code map (hardcoded, keeps the module grpc-free).grpc call(agctl/commands/grpc_commands.py) — template + free-form modes; unary/client-streaming return one envelope; server-streaming/bidi stream NDJSON to stdout and consume NDJSON from stdin (the bidirectional streaming symmetry), with signal-driven stop + a terminal-statussummary.grpc healthcheck(the gRPC analog ofcheck ready).grpc-servicesandgrpc-methodscategories (target listing + method request-field schema).grpcextra (grpcio,grpcio-tools,grpcio-health-checking,grpcio-reflection,protobuf,jq); added to theintegrationaggregate and the CI install line. In-tree — no new entry-point group.Design decisions (spec D1–D13)
In-tree (not a plugin); reflection-first with descriptor fallback; JSON in/out for messages; all four call types via stdin/stdout NDJSON symmetry;
package.Service/Methodaddressing +--addressno-config mode; status-as-result; unary assertions reuse jq/subset/equals; gRPC metadata + trailers; TLS/plaintext mirroringkafka.ssl; descriptor-driven dynamic stubs (no codegen).Testing
pytest.importorskip), so the suite collects and runs without thegrpcextra.tests/integration/test_grpc_commands.py): an in-process grpcioEchoserver (all four call types + reflection + health), self-skipping withoutAGCTL_TEST_LIVE=1/AGCTL_TEST_GRPC_ADDR.tlsfields now honored; streaming mid-run errors emit a summary line, never a raw traceback).Known limitations / deferred (post-merge)
Tracked in
.superpowers/sdd/progress.md: descriptor-pool is resolved per call (no caching — reflection/protocruns once per invocation); a now-unreachable streamingNotImplementedErrorstub in_grpc_call_core; a latentself._grpcattribute path on the channel-injected DI seam (not hit in production);--matchroot semantics (envelope on unary, message on streams) noted in docstrings but not the CLI help; minor DRY/coverage nits. Cross-message ordering assertions and a gRPC mock server are out of scope (future work).References
docs/superpowers/specs/active/2026-07-09-grpc-support-design.mddocs/superpowers/plans/active/2026-07-09-grpc-support.md🤖 Generated with Claude Code