Cursor Skill

use-protobuf

Design, change, and review Protobuf schemas used as gRPC contracts, streaming protocols, typed data models, grpc-gateway REST APIs, OpenAPI specifications, or generated SDK inputs. Use for .proto files, RPC request/response design, oneof stream events, validation annotations, API

LLM Mart · 0 points · 11 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download moeru-ai-auv-.agents_skills_use-protobuf-372a07b.zip · 8 KB
moeru-ai/auv 51 6 forks Apache-2.0 Updated 10h ago
Part of moeru-ai/auv — 28 skills

Install

skills CLI npx skills add https://github.com/moeru-ai/auv/tree/main/.agents/skills/use-protobuf
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install moeru-ai-auv@llmmart
Git git clone https://github.com/moeru-ai/auv.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole moeru-ai/auv collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Use Protobuf

Treat Protobuf as the canonical typed contract for gRPC, REST gateway bindings, OpenAPI, generated SDKs, and shared data structures. Model the domain before optimizing generated code.

Workflow

  1. Read repository instructions and inspect existing .proto files, packages, versions, imports, generation configuration, and generated output conventions.
  2. Classify each service as gRPC-only or HTTP-exposed before adding annotations.
  3. Model every RPC, stream packet, enum, error, and reusable message with concrete types.
  4. Apply transport-specific validation and documentation rules.
  5. Evaluate compatibility according to the package's release state and version.
  6. Generate every configured SDK and OpenAPI artifact. Use $use-buf and $use-buf-plugins when available.
  7. Run repository tests and inspect generated diffs; never hand-edit generated code.

Define RPC Contracts Explicitly

  • Define a dedicated RPC method for every gRPC operation.
  • Name unary messages MethodRequest and MethodResponse.
  • Keep request and response messages distinct even when their current fields happen to match.
  • Use TitleCase service, method, message, and enum names; use lower_snake_case fields and UPPER_SNAKE_CASE enum values.
  • Prefer comments that explain semantics, units, identity, presence, ordering, and lifecycle rather than restating the field name.
rpc GetDocument(GetDocumentRequest) returns (GetDocumentResponse);

Model Streaming Without Base Payloads

Use the appropriate gRPC streaming form:

rpc ImportRecords(stream ImportRecordsStreamRequest) returns (ImportRecordsResponse);
rpc WatchJob(WatchJobRequest) returns (stream WatchJobStreamResponse);
rpc Transfer(stream TransferStreamRequest) returns (stream TransferStreamResponse);

MUST NOT create an abstract, generic, inherited, or catch-all base event/base payload for stream requests or responses. Define concrete stream event, step, or packet messages. When several variants may occur, use oneof whose alternatives are separate messages. Use one homogeneous stream message only when every packet genuinely has the same body and semantics, such as fixed-shape file chunks.

Read references/schema-design.md before designing or changing any streaming RPC.

Separate gRPC-Only and HTTP-Exposed Schemas

For gRPC-only services, do not add google.api.http, grpc-gateway, or grpc.gateway.protoc_gen_openapiv2 imports, method options, message options, enum options, or field options.

For every *Request exposed through grpc-gateway, regardless of GET, POST, body, path, or query placement:

  • validate accepted input with buf.validate annotations;
  • document every request field with appropriate openapiv2 information such as example, description, format, range, length, pattern, or collection bounds;
  • keep runtime validation authoritative and make OpenAPI constraints agree with it;
  • define the google.api.http binding and operation documentation intentionally.

Do not hardcode a Buf cache path when researching extension fields. Follow the export/query workflow in references/http-and-openapi.md.

Prefer Strong Domain Types

  • Use an enum whenever the value belongs to a finite controlled vocabulary; do not disguise it as an unconstrained string.
  • Give enums an explicit zero value and document what the enum classifies.
  • Prefer dedicated messages, well-known types, repeated fields, maps, and oneof over google.protobuf.Struct or google.protobuf.Any.
  • Use Struct or Any only for a real open-world boundary. Document why typed modeling is impossible and how consumers validate the payload.
  • In Go, use protojson for Protobuf JSON and a registered type resolver for Any; do not route Protobuf through generic encoding/json. Research the canonical library for every other target language before implementing serialization.

Organize and Version Schemas

  • Set go_package on first-party schemas that generate Go.
  • Keep language-neutral source paths and verify Python output with protoc-gen-python plus protoc-gen-pyi. Do not assume a kebab-case Protobuf source/import path automatically makes Python output invalid, and do not rename the source tree merely out of fear that it might violate Python module conventions; generate and verify the selected plugins' actual module/import behavior.
  • Put API versions in both package and directory identity, using forms such as v1, v2, v1alpha1, or v1beta1.
  • Before release, while a feature is explicitly experimental or feature-flagged, allow deliberate breaking redesigns and field renumbering only when every producer, consumer, stored payload, and generated artifact can be rebuilt together.
  • After release, never renumber or reuse field numbers. Reserve removed field numbers and names, and introduce a new version for incompatible redesigns.
  • Keep generated Go packages, Python modules, TypeScript modules, and other SDK paths aligned with the source schema path. Preserve each language plugin's conventional leaf layout.
  • Change output directories or flattening only when the user explicitly requests it or the repository already declares that convention in generation configuration.

Generate Complete SDK Surfaces

  • Generate runtime code and the language's customary typing artifacts.
  • For Python, generate .py plus .pyi when supported.
  • For TypeScript, generate .ts or the ecosystem-appropriate .d.ts/.d.mts artifacts.
  • Prefer the established generator for each language and OpenAPI ecosystem. Do not write a parallel custom generator or manually maintain generated output.

Read references/schema-design.md for complete modeling and evolution rules, references/http-and-openapi.md for gateway schemas, and references/api-design-sources.md when designing public resources, errors, pagination, or long-running operations.

Files (auv)
  • agents
    • openai.yaml 196 B
      interface:
        display_name: "Use Protobuf"
        short_description: "Design robust gRPC and HTTP Protobuf schemas"
        default_prompt: "Use $use-protobuf to design or review this Protobuf API contract."
      
  • references
    • api-design-sources.md 2 KB
      # API and Protobuf Design Sources
      
      Use these as selected references, not as mutually mandatory specifications. Preserve the repository's established API style unless the user requests a migration.
      
      - [Protocol Buffers style guide](https://protobuf.dev/programming-guides/style/): file layout, identifier casing, enum zero values, services, and naming hazards.
      - [Proto3 language guide](https://protobuf.dev/programming-guides/proto3/): field numbers, presence, `oneof`, imports, `Any`, JSON mapping, and compatible evolution.
      - [gRPC core concepts](https://grpc.io/docs/what-is-grpc/core-concepts/): unary, client-streaming, server-streaming, bidirectional-streaming, cancellation, deadlines, and metadata.
      - [JSON:API error objects](https://jsonapi.org/format/#errors): structured HTTP error identity, status, code, title, detail, source, links, and metadata.
      - [Microsoft REST API Guidelines](https://github.com/microsoft/api-guidelines): public REST consistency, resources, methods, errors, versioning, pagination, and long-running operations.
      - [Kratos Protobuf guideline](https://go-kratos.dev/docs/guide/api-protobuf/): API directory/version organization, HTTP annotations, and generated service conventions.
      - [Boston Dynamics API Protobuf guidelines](https://dev.bostondynamics.com/docs/protos/style_guide.html): production schema conventions, services, errors, timestamps, units, and compatibility.
      - [VictoriaMetrics Practical Protobuf](https://victoriametrics.com/blog/go-protobuf-basic/): practical Go/Protobuf encoding and generated-code considerations; cross-check advice against official Protobuf compatibility rules.
      - [Go generated code guide](https://protobuf.dev/reference/go/go-generated/): `go_package`, generated package mapping, and Go API generation.
      - [Python generated code guide](https://protobuf.dev/reference/python/python-generated/): Python module generation and runtime behavior.
      
      When sources disagree, prioritize wire compatibility, explicit repository policy, official Protobuf/gRPC behavior, and the user's stated API lifecycle.
      
    • http-and-openapi.md 3.7 KB
      # grpc-gateway, Validation, and OpenAPI
      
      ## Classify the Transport
      
      For gRPC-only services, omit all of the following:
      
      - `google/api/annotations.proto` and `google.api.http`;
      - `protoc-gen-openapiv2/options/annotations.proto`;
      - grpc-gateway/OpenAPI service, operation, message, enum, and field options.
      
      Keep ordinary Protobuf comments and runtime validation when required by the gRPC service itself, but do not make a gRPC-only contract depend on an HTTP documentation toolchain.
      
      For an HTTP-exposed RPC, define the binding and document the operation:
      
      ```proto
      rpc CreateWidget(CreateWidgetRequest) returns (CreateWidgetResponse) {
        option (google.api.http) = {
          post: "/v1/widgets"
          body: "*"
        };
        option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
          operation_id: "widgets_create"
          summary: "Create a widget."
          tags: "Widgets"
        };
      }
      ```
      
      ## Validate Every HTTP Request
      
      Apply Protovalidate to every accepted request field regardless of whether it comes from a path, query string, GET request, POST body, or other HTTP method. Validate strings, numbers, enums, collections, nested messages, cross-field constraints, and identifiers according to domain semantics.
      
      ```proto
      message ListWidgetsRequest {
        string parent = 1 [
          (buf.validate.field).string = {
            min_len: 1
            max_len: 200
          },
          (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
            description: "Parent collection identifier."
            example: "\"accounts/42\""
          }
        ];
        int32 page_size = 2 [
          (buf.validate.field).int32 = {
            gte: 0
            lte: 100
          },
          (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
            description: "Maximum number of widgets to return."
            example: "50"
            minimum: 0
            maximum: 100
          }
        ];
      }
      ```
      
      Treat validation as the executable acceptance rule. Mirror relevant range, pattern, length, format, example, description, and collection information into OpenAPI so generated clients and documentation do not contradict runtime behavior.
      
      ## Inspect Extension Definitions Without Cache Paths
      
      Do not hardcode `~/.cache`, platform-specific cache roots, module digests, or commit directories. Inspect the dependency declared in `buf.yaml` and pinned in `buf.lock`, then use Buf:
      
      ```sh
      buf dep graph --format json
      
      inspection_dir="$(mktemp -d)"
      buf export buf.build/grpc-ecosystem/grpc-gateway:<pinned-ref> \
        --path protoc-gen-openapiv2/options/annotations.proto \
        --path protoc-gen-openapiv2/options/openapiv2.proto \
        --output "$inspection_dir"
      
      rg -n "message JSONSchema|openapiv2_field|example|description" "$inspection_dir"
      ```
      
      Resolve `<pinned-ref>` from repository configuration/lock state. Remove the temporary directory after inspection. Consult `$use-buf` for dependency resolution and `$use-buf-plugins` for generator behavior.
      
      The grpc-gateway OpenAPI documentation explains comment propagation, operation/schema/field options, visibility, merge behavior, enum rendering, and output configuration:
      
      - https://grpc-ecosystem.github.io/grpc-gateway/docs/mapping/customizing_openapi_output/
      
      ## Public HTTP API Shape
      
      Use a consistent resource and error model. When the application adopts JSON:API errors, model typed equivalents of useful members such as status, code, title, detail, source pointer/parameter/header, links, and meta rather than returning an unstructured object. Do not combine mutually incompatible envelope conventions without an explicit API-wide decision.
      
      Use the Microsoft API Guidelines and JSON:API as design references for resource naming, HTTP semantics, pagination, idempotency, errors, and long-running operations. Adapt them to the existing API contract rather than importing conventions piecemeal.
      
    • schema-design.md 5.5 KB
      # Protobuf Schema Design
      
      ## Contents
      
      - RPC and message boundaries
      - Streaming protocols
      - Strong typing and presence
      - Reuse without abstraction leakage
      - Evolution and versioning
      - Source and generated layout
      
      ## RPC and Message Boundaries
      
      Give each operation its own request and response, named after the method:
      
      ```proto
      service CatalogService {
        rpc CreateItem(CreateItemRequest) returns (CreateItemResponse);
        rpc GetItem(GetItemRequest) returns (GetItemResponse);
      }
      ```
      
      Do not use a generic `Request`, `Response`, `Payload`, or `Envelope` across unrelated methods. Dedicated messages allow validation, documentation, authorization, and evolution to diverge safely.
      
      Model method inputs in the request even when the transport could carry them elsewhere. Model method results in the response instead of returning a domain entity directly; the response leaves room for metadata and future compatible fields.
      
      ## Streaming Protocols
      
      Choose the cardinality from behavior:
      
      - client streaming: large or incremental input such as JSON records, file chunks, or query batches;
      - server streaming: progress, events, task steps, query results, or binary output;
      - bidirectional streaming: interactive/duplex protocols where both sides advance independently.
      
      MUST NOT define abstract or generic base stream events or payloads. For heterogeneous streams, use separate messages under `oneof`:
      
      ```proto
      message WatchImportStreamResponse {
        oneof event {
          ImportStarted started = 1;
          ImportProgress progress = 2;
          ImportWarning warning = 3;
          ImportCompleted completed = 4;
        }
      }
      
      message ImportStarted {
        string import_id = 1;
      }
      
      message ImportProgress {
        int64 records_processed = 1;
        optional int64 records_total = 2;
      }
      ```
      
      Use the same structure for heterogeneous client streams. For example, define separate header, JSON record, file chunk, commit, and abort messages rather than a base packet with many nullable fields.
      
      Use one homogeneous stream message only when every packet has exactly the same semantics. A fixed-shape file chunk can be:
      
      ```proto
      message DownloadFileStreamResponse {
        bytes data = 1;
      }
      ```
      
      If the stream also carries headers, checksums, progress, or trailers, return to `oneof` with concrete variants.
      
      Document ordering, which event may appear first/last, repetition, completion, cancellation, resumability, offsets, checksums, and whether an error arrives as gRPC status or an in-band event.
      
      ## Strong Typing and Presence
      
      - Use enums for finite controlled vocabularies. Prefix top-level enum values with the enum name and give the zero value `_UNSPECIFIED` or `_UNKNOWN` semantics.
      - Use `optional` when presence differs from the scalar default. Do not add presence when unset and default are semantically identical.
      - Use `google.protobuf.Timestamp`, `Duration`, `FieldMask`, or other appropriate well-known types instead of strings with implicit formats.
      - Include units in names or comments for numeric quantities, such as `timeout_seconds` or `size_bytes`.
      - Use `bytes` for opaque binary content, not base64 text fields.
      - Use maps only for truly dynamic keyed collections. Prefer repeated typed entries when keys or values need validation, ordering, metadata, or future evolution.
      - Avoid `Struct` and `Any`. If an upstream opaque payload must be preserved, isolate it at that boundary, document its schema/version and validation, and provide typed projections for first-class fields.
      
      For Go JSON conversion, use `google.golang.org/protobuf/encoding/protojson`. For `Any`, configure a resolver/type registry. Research and use the canonical Protobuf JSON/runtime API in every other language.
      
      ## Reuse Without Abstraction Leakage
      
      Reuse a message when two fields mean the same contract and must evolve together. Import the canonical message instead of duplicating its fields and writing conversion code. Keep package dependency direction intentional and acyclic.
      
      Do not reuse merely because two messages currently have the same shape. Separate them when their ownership, validation, authorization, lifecycle, or future evolution differs. Never introduce a generic base request/response/event solely to reduce line count.
      
      ## Evolution and Versioning
      
      Before a feature is released, while explicitly experimental or feature-flagged, a coordinated breaking redesign may change structure or field numbers. Rebuild all generated SDKs, services, clients, fixtures, queues, and stored payloads together, and still run breaking-change detection so the break is visible.
      
      After release:
      
      - never change or reuse a field number;
      - reserve deleted numbers and names;
      - add fields compatibly whenever possible;
      - avoid moving fields into or out of an existing `oneof` without studying wire behavior;
      - introduce `v2` for incompatible changes;
      - use `v1alpha1`/`v1beta1` to signal unstable contracts when appropriate.
      
      Put the version in both directory and package identity, for example `example/catalog/v1` and `example.catalog.v1`. Keep imports explicit and avoid confusing relative resolution across packages.
      
      ## Source and Generated Layout
      
      - Name source files `lower_snake_case.proto`.
      - Sort imports and set language file options such as `go_package` where required by the project's generation model.
      - Keep source directories language-neutral.
      - Preserve the schema's path in generated Go, Python, TypeScript, and other targets unless the language plugin's established convention adds a conventional leaf directory.
      - Verify Python with runtime and typing plugins instead of reorganizing the schema tree preemptively.
      - Never edit generated files by hand.
      
  • SKILL.md 6.3 KB
    ---
    name: use-protobuf
    description: Design, change, and review Protobuf schemas used as gRPC contracts, streaming protocols, typed data models, grpc-gateway REST APIs, OpenAPI specifications, or generated SDK inputs. Use for .proto files, RPC request/response design, oneof stream events, validation annotations, API versioning, schema evolution, generated package layout, and avoiding weak Struct or Any payloads.
    ---
    
    # Use Protobuf
    
    Treat Protobuf as the canonical typed contract for gRPC, REST gateway bindings, OpenAPI, generated SDKs, and shared data structures. Model the domain before optimizing generated code.
    
    ## Workflow
    
    1. Read repository instructions and inspect existing `.proto` files, packages, versions, imports, generation configuration, and generated output conventions.
    2. Classify each service as gRPC-only or HTTP-exposed before adding annotations.
    3. Model every RPC, stream packet, enum, error, and reusable message with concrete types.
    4. Apply transport-specific validation and documentation rules.
    5. Evaluate compatibility according to the package's release state and version.
    6. Generate every configured SDK and OpenAPI artifact. Use `$use-buf` and `$use-buf-plugins` when available.
    7. Run repository tests and inspect generated diffs; never hand-edit generated code.
    
    ## Define RPC Contracts Explicitly
    
    - Define a dedicated RPC method for every gRPC operation.
    - Name unary messages `MethodRequest` and `MethodResponse`.
    - Keep request and response messages distinct even when their current fields happen to match.
    - Use TitleCase service, method, message, and enum names; use `lower_snake_case` fields and `UPPER_SNAKE_CASE` enum values.
    - Prefer comments that explain semantics, units, identity, presence, ordering, and lifecycle rather than restating the field name.
    
    ```proto
    rpc GetDocument(GetDocumentRequest) returns (GetDocumentResponse);
    ```
    
    ## Model Streaming Without Base Payloads
    
    Use the appropriate gRPC streaming form:
    
    ```proto
    rpc ImportRecords(stream ImportRecordsStreamRequest) returns (ImportRecordsResponse);
    rpc WatchJob(WatchJobRequest) returns (stream WatchJobStreamResponse);
    rpc Transfer(stream TransferStreamRequest) returns (stream TransferStreamResponse);
    ```
    
    MUST NOT create an abstract, generic, inherited, or catch-all base event/base payload for stream requests or responses. Define concrete stream event, step, or packet messages. When several variants may occur, use `oneof` whose alternatives are separate messages. Use one homogeneous stream message only when every packet genuinely has the same body and semantics, such as fixed-shape file chunks.
    
    Read [references/schema-design.md](references/schema-design.md) before designing or changing any streaming RPC.
    
    ## Separate gRPC-Only and HTTP-Exposed Schemas
    
    For gRPC-only services, do not add `google.api.http`, grpc-gateway, or `grpc.gateway.protoc_gen_openapiv2` imports, method options, message options, enum options, or field options.
    
    For every `*Request` exposed through grpc-gateway, regardless of GET, POST, body, path, or query placement:
    
    - validate accepted input with `buf.validate` annotations;
    - document every request field with appropriate `openapiv2` information such as example, description, format, range, length, pattern, or collection bounds;
    - keep runtime validation authoritative and make OpenAPI constraints agree with it;
    - define the `google.api.http` binding and operation documentation intentionally.
    
    Do not hardcode a Buf cache path when researching extension fields. Follow the export/query workflow in [references/http-and-openapi.md](references/http-and-openapi.md).
    
    ## Prefer Strong Domain Types
    
    - Use an enum whenever the value belongs to a finite controlled vocabulary; do not disguise it as an unconstrained string.
    - Give enums an explicit zero value and document what the enum classifies.
    - Prefer dedicated messages, well-known types, repeated fields, maps, and `oneof` over `google.protobuf.Struct` or `google.protobuf.Any`.
    - Use `Struct` or `Any` only for a real open-world boundary. Document why typed modeling is impossible and how consumers validate the payload.
    - In Go, use `protojson` for Protobuf JSON and a registered type resolver for `Any`; do not route Protobuf through generic `encoding/json`. Research the canonical library for every other target language before implementing serialization.
    
    ## Organize and Version Schemas
    
    - Set `go_package` on first-party schemas that generate Go.
    - Keep language-neutral source paths and verify Python output with `protoc-gen-python` plus `protoc-gen-pyi`. Do not assume a kebab-case Protobuf source/import path automatically makes Python output invalid, and do not rename the source tree merely out of fear that it might violate Python module conventions; generate and verify the selected plugins' actual module/import behavior.
    - Put API versions in both package and directory identity, using forms such as `v1`, `v2`, `v1alpha1`, or `v1beta1`.
    - Before release, while a feature is explicitly experimental or feature-flagged, allow deliberate breaking redesigns and field renumbering only when every producer, consumer, stored payload, and generated artifact can be rebuilt together.
    - After release, never renumber or reuse field numbers. Reserve removed field numbers and names, and introduce a new version for incompatible redesigns.
    - Keep generated Go packages, Python modules, TypeScript modules, and other SDK paths aligned with the source schema path. Preserve each language plugin's conventional leaf layout.
    - Change output directories or flattening only when the user explicitly requests it or the repository already declares that convention in generation configuration.
    
    ## Generate Complete SDK Surfaces
    
    - Generate runtime code and the language's customary typing artifacts.
    - For Python, generate `.py` plus `.pyi` when supported.
    - For TypeScript, generate `.ts` or the ecosystem-appropriate `.d.ts`/`.d.mts` artifacts.
    - Prefer the established generator for each language and OpenAPI ecosystem. Do not write a parallel custom generator or manually maintain generated output.
    
    Read [references/schema-design.md](references/schema-design.md) for complete modeling and evolution rules, [references/http-and-openapi.md](references/http-and-openapi.md) for gateway schemas, and [references/api-design-sources.md](references/api-design-sources.md) when designing public resources, errors, pagination, or long-running operations.
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related